我想保持我的.bashrc和.bash_login文件在版本控制,以便我可以在我使用的所有计算机之间使用它们。问题是我有一些操作系统特定的别名,所以我正在寻找一种方法来确定脚本是否在Mac OS X, Linux或Cygwin上运行。

在Bash脚本中检测操作系统的正确方法是什么?


当前回答

我倾向于将.bashrc和.bash_alias保存在所有平台都可以访问的文件共享中。这就是我如何在我的.bash_alias中克服这个问题:

if [[ -f (name of share)/.bash_alias_$(uname) ]]; then
    . (name of share)/.bash_alias_$(uname)
fi

我有一个。bash_alias_linux的例子:

alias ls='ls --color=auto'

通过这种方式,我将特定于平台的代码和可移植的代码分开,你可以对.bashrc做同样的事情

其他回答

我认为以下几点应该有用。不过我对win32不太确定。

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        # ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
        # Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
        # POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
        # Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
        # I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
        # ...
else
        # Unknown.
fi

bash manpage说变量OSTYPE存储了操作系统的名称:

OSTYPE自动设置为描述bash正在执行的操作系统的字符串。默认为system- 相关的。

它在这里被设置为linux-gnu。

试试这个:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"

如果有人对检测WSL和WSL版本2感兴趣,我也会使用这个工具。

#!/usr/bin/env bash

unameOut=$(uname -a)
case "${unameOut}" in
    *Microsoft*)     OS="WSL";; #must be first since Windows subsystem for linux will have Linux in the name too
    *microsoft*)     OS="WSL2";; #WARNING: My v2 uses ubuntu 20.4 at the moment slightly different name may not always work
    Linux*)     OS="Linux";;
    Darwin*)    OS="Mac";;
    CYGWIN*)    OS="Cygwin";;
    MINGW*)     OS="Windows";;
    *Msys)     OS="Windows";;
    *)          OS="UNKNOWN:${unameOut}"
esac

echo ${OS};

OSTYPE美元

你可以简单地使用预定义的$OSTYPE变量,例如:

case "$OSTYPE" in
  solaris*) echo "SOLARIS" ;;
  darwin*)  echo "OSX" ;; 
  linux*)   echo "LINUX" ;;
  bsd*)     echo "BSD" ;;
  msys*)    echo "WINDOWS" ;;
  cygwin*)  echo "ALSO WINDOWS" ;;
  *)        echo "unknown: $OSTYPE" ;;
esac

但是,旧的shell(如Bourne shell)不能识别它。


生命

另一种方法是基于uname命令检测平台。

请参阅以下脚本(已准备好包含在.bashrc中):

# Detect the platform (similar to $OSTYPE)
OS="`uname`"
case $OS in
  'Linux')
    OS='Linux'
    alias ls='ls --color=auto'
    ;;
  'FreeBSD')
    OS='FreeBSD'
    alias ls='ls -G'
    ;;
  'WindowsNT')
    OS='Windows'
    ;;
  'Darwin') 
    OS='Mac'
    ;;
  'SunOS')
    OS='Solaris'
    ;;
  'AIX') ;;
  *) ;;
esac

你可以在我的.bashrc中找到一些实际的例子。


以下是在Travis CI上使用的类似版本:

case $(uname | tr '[:upper:]' '[:lower:]') in
  linux*)
    export TRAVIS_OS_NAME=linux
    ;;
  darwin*)
    export TRAVIS_OS_NAME=osx
    ;;
  msys*)
    export TRAVIS_OS_NAME=windows
    ;;
  *)
    export TRAVIS_OS_NAME=notset
    ;;
esac