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

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


当前回答

检测操作系统和CPU类型并不容易移植。我有一个大约100行的sh脚本,可以在非常广泛的Unix平台上运行:自1988年以来我使用过的任何系统。

关键要素是

uname -p是处理器类型,但在现代Unix平台上通常是未知的。 uname -m将在某些Unix系统上给出“机器硬件名称”。 /bin/arch,如果存在,通常会给出处理器的类型。 不带参数的Uname将命名操作系统。

最终,你将不得不考虑平台之间的区别,以及你想把它们做得多好。例如,为了简单起见,我将i386到i686,任何“奔腾*”和任何“AMD*Athlon*”都视为x86。

我的~ /。profile在启动时运行一个a脚本,该脚本将一个变量设置为一个字符串,表示CPU和操作系统的组合。我有特定于平台的bin, man, lib,并包括基于此设置的目录。然后我设置了大量的环境变量。例如,重新格式化邮件的shell脚本可以调用$LIB/mailfmt,这是一个特定于平台的可执行二进制文件。

如果你想抄近路,uname -m和普通的uname会在很多平台上告诉你你想知道什么。当你需要的时候添加其他东西。(和用例,不嵌套if!)

其他回答

检测操作系统和CPU类型并不容易移植。我有一个大约100行的sh脚本,可以在非常广泛的Unix平台上运行:自1988年以来我使用过的任何系统。

关键要素是

uname -p是处理器类型,但在现代Unix平台上通常是未知的。 uname -m将在某些Unix系统上给出“机器硬件名称”。 /bin/arch,如果存在,通常会给出处理器的类型。 不带参数的Uname将命名操作系统。

最终,你将不得不考虑平台之间的区别,以及你想把它们做得多好。例如,为了简单起见,我将i386到i686,任何“奔腾*”和任何“AMD*Athlon*”都视为x86。

我的~ /。profile在启动时运行一个a脚本,该脚本将一个变量设置为一个字符串,表示CPU和操作系统的组合。我有特定于平台的bin, man, lib,并包括基于此设置的目录。然后我设置了大量的环境变量。例如,重新格式化邮件的shell脚本可以调用$LIB/mailfmt,这是一个特定于平台的可执行二进制文件。

如果你想抄近路,uname -m和普通的uname会在很多平台上告诉你你想知道什么。当你需要的时候添加其他东西。(和用例,不嵌套if!)

在bash中,使用$OSTYPE和$HOSTTYPE,如文档所示;这就是我的工作。如果这还不够,如果甚至uname或uname -a(或其他适当的选项)都没有提供足够的信息,那么总是有配置。猜测脚本来自GNU项目,正是为了这个目的。

我认为以下几点应该有用。不过我对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

执行以下操作可以帮助正确执行ubuntu检查:

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi

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

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

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