如何从 Bash 脚本中检测操作系统?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/394230/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect the OS from a Bash script?
提问by csexton
I would like to keep my .bashrc
and .bash_login
files in version control so that I can use them between all the computers I use. The problem is I have some OS specific aliases so I was looking for a way to determine if the script is running on Mac OS X, Linux or Cygwin.
我想将我的.bashrc
和.bash_login
文件保持在版本控制中,以便我可以在我使用的所有计算机之间使用它们。问题是我有一些特定于操作系统的别名,所以我正在寻找一种方法来确定脚本是在 Mac OS X、Linux 还是Cygwin 上运行。
What is the proper way to detect the operating system in a Bashscript?
在Bash脚本中检测操作系统的正确方法是什么?
采纳答案by Timmmm
I think the following should work. I'm not sure about win32
though.
我认为以下应该有效。我不确定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
回答by Nicolas Martyanoff
For my .bashrc, I use the following code:
对于我的 .bashrc,我使用以下代码:
platform='unknown'
unamestr=`uname`
if [[ "$unamestr" == 'Linux' ]]; then
platform='linux'
elif [[ "$unamestr" == 'FreeBSD' ]]; then
platform='freebsd'
fi
Then I do somethings like:
然后我做这样的事情:
if [[ $platform == 'linux' ]]; then
alias ls='ls --color=auto'
elif [[ $platform == 'freebsd' ]]; then
alias ls='ls -G'
fi
It's ugly, but it works. You may use case
instead of if
if you prefer.
这很丑陋,但它有效。如果您愿意,可以使用case
代替if
。
回答by Johannes Schaub - litb
The bash manpage says that the variable OSTYPE stores the name of the operation system:
bash 手册页说变量 OSTYPE 存储操作系统的名称:
OSTYPE
Automatically set to a string that describes the operating system on which bash is executing. The default is system- dependent.
OSTYPE
自动设置为描述执行 bash 的操作系统的字符串。默认值取决于系统。
It is set to linux-gnu
here.
设置到linux-gnu
这里。
回答by kenorb
$OSTYPE
$OSTYPE
You can simply use pre-defined $OSTYPE
variable e.g.:
您可以简单地使用预定义的$OSTYPE
变量,例如:
case "$OSTYPE" in
solaris*) echo "SOLARIS" ;;
darwin*) echo "OSX" ;;
linux*) echo "LINUX" ;;
bsd*) echo "BSD" ;;
msys*) echo "WINDOWS" ;;
*) echo "unknown: $OSTYPE" ;;
esac
However it's not recognized by the older shells(such as Bourne shell).
但是,旧的 shell(例如Bourne shell)无法识别它。
uname
uname
Another method is to detect platform based on uname
command.
另一种方法是基于uname
命令检测平台。
See the following script (ready to include in .bashrc):
请参阅以下脚本(已准备好包含在 .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
You can find some practical example in my .bashrc
.
Here is similar version used on Travis CI:
这是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
回答by Norman Ramsey
Detecting operating system and CPU typeis not so easy to do portably. I have a sh
script of about 100 lines that works across a very wide variety of Unix platforms: any system I have used since 1988.
检测操作系统和 CPU 类型并不是那么容易便携。我有一个sh
大约 100 行的脚本,可以在非常广泛的 Unix 平台上运行:自 1988 年以来我使用过的任何系统。
The key elements are
关键要素是
uname -p
is processor typebut is usuallyunknown
on modern Unix platforms.uname -m
will give the "machine hardware name" on some Unix systems./bin/arch
, if it exists, will usually give the type of processor.uname
with no arguments will name the operating system.
uname -p
是处理器类型,但通常unknown
在现代 Unix 平台上。uname -m
将在某些 Unix 系统上给出“机器硬件名称”。/bin/arch
,如果存在,通常会给出处理器的类型。uname
不带参数将命名操作系统。
Eventually you will have to think about the distinctions between platforms and how fine you want to make them.For example, just to keep things simple, I treat i386
through i686
, any "Pentium*
" and any "AMD*Athlon*
" all as x86
.
最终,您将不得不考虑平台之间的区别以及您想让它们做得多好。例如,只是为了让事情变得简单,我把i386
通过i686
,任何“ Pentium*
”任何“ AMD*Athlon*
”所有的x86
。
My ~/.profile
runs an a script at startup which sets one variable to a string indicating the combination of CPU and operating system. I have platform-specific bin
, man
, lib
, and include
directories that get set up based on that. Then I set a boatload of environment variables. So for example, a shell script to reformat mail can call, e.g., $LIB/mailfmt
which is a platform-specific executable binary.
我~/.profile
在启动时运行一个脚本,它将一个变量设置为一个字符串,指示 CPU 和操作系统的组合。我有特定于平台的bin
,man
,lib
,和include
基于该是那些获得建立目录。然后我设置了一大堆环境变量。因此,例如,重新格式化邮件的 shell 脚本可以调用,例如,$LIB/mailfmt
它是特定于平台的可执行二进制文件。
If you want to cut corners, uname -m
and plain uname
will tell you what you want to know on many platforms. Add other stuff when you need it. (And use case
, not nested if
!)
如果你想偷工减料,uname -m
plainuname
会在很多平台上告诉你你想知道什么。需要时添加其他内容。(并使用case
,不嵌套if
!)
回答by coto
I recommend to use this complete bash code
我建议使用这个完整的 bash 代码
lowercase(){
echo "" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}
OS=`lowercase \`uname\``
KERNEL=`uname -r`
MACH=`uname -m`
if [ "{$OS}" == "windowsnt" ]; then
OS=windows
elif [ "{$OS}" == "darwin" ]; then
OS=mac
else
OS=`uname`
if [ "${OS}" = "SunOS" ] ; then
OS=Solaris
ARCH=`uname -p`
OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
elif [ "${OS}" = "AIX" ] ; then
OSSTR="${OS} `oslevel` (`oslevel -r`)"
elif [ "${OS}" = "Linux" ] ; then
if [ -f /etc/redhat-release ] ; then
DistroBasedOn='RedHat'
DIST=`cat /etc/redhat-release |sed s/\ release.*//`
PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/SuSE-release ] ; then
DistroBasedOn='SuSe'
PSUEDONAME=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
elif [ -f /etc/mandrake-release ] ; then
DistroBasedOn='Mandrake'
PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/debian_version ] ; then
DistroBasedOn='Debian'
DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F= '{ print }'`
PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F= '{ print }'`
REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F= '{ print }'`
fi
if [ -f /etc/UnitedLinux-release ] ; then
DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
fi
OS=`lowercase $OS`
DistroBasedOn=`lowercase $DistroBasedOn`
readonly OS
readonly DIST
readonly DistroBasedOn
readonly PSUEDONAME
readonly REV
readonly KERNEL
readonly MACH
fi
fi
more examples examples here: https://github.com/coto/server-easy-install/blob/master/lib/core.sh
更多示例示例:https: //github.com/coto/server-easy-install/blob/master/lib/core.sh
回答by Teddy
In bash, use $OSTYPE
and $HOSTTYPE
, as documented; this is what I do. If that is not enough, and if even uname
or uname -a
(or other appropriate options) does not give enough information, there's always the config.guessscript from the GNU project, made exactly for this purpose.
在 bash 中,使用$OSTYPE
and $HOSTTYPE
,如文档所述;这就是我所做的。如果这还不够,甚至uname
或uname -a
(或其他适当的选项)没有提供足够的信息,那么总是有来自 GNU 项目的config.guess脚本,正是为此目的而制作的。
回答by Joao da Silva
Try using "uname". For example, in Linux: "uname -a".
尝试使用“uname”。例如,在 Linux 中:“uname -a”。
According to the manual page, uname conforms to SVr4 and POSIX, so it should be available on Mac OS X and Cygwintoo, but I can't confirm that.
根据手册页,uname 符合 SVr4 和 POSIX,所以它应该也适用于 Mac OS X 和Cygwin,但我无法确认。
BTW: $OSTYPE is also set to linux-gnu
here :)
顺便说一句:$OSTYPE 也设置在linux-gnu
这里 :)
回答by Akiva
I would suggest avoiding some of these answers. Don't forget that you can choose other forms of string comparison, which would clear up most of the variations, or ugly code offered.
我建议避免其中一些答案。不要忘记,您可以选择其他形式的字符串比较,这将清除大多数变体或提供的丑陋代码。
One such solution would be a simple check, such as:
一个这样的解决方案是一个简单的检查,例如:
if [[ "$OSTYPE" =~ ^darwin ]]; then
if [[ "$OSTYPE" =~ ^darwin ]]; then
Which has the added benefit of matching any version of Darwin, despite it's version suffix. This also works for any variations of Linux
one may expect.
尽管它是版本后缀,但它具有匹配任何版本的 Darwin 的额外好处。这也适用于Linux
人们可能期望的任何变化。
You can see some additional examples within my dotfiles here
您可以在此处查看我的 dotfiles 中的一些其他示例
回答by kfix
I wrote these sugars in my .bashrc
:
我在我的.bashrc
:
if_os () { [[ $OSTYPE == ** ]]; }
if_nix () {
case "$OSTYPE" in
*linux*|*hurd*|*msys*|*cygwin*|*sua*|*interix*) sys="gnu";;
*bsd*|*darwin*) sys="bsd";;
*sunos*|*solaris*|*indiana*|*illumos*|*smartos*) sys="sun";;
esac
[[ "${sys}" == "" ]];
}
So I can do stuff like:
所以我可以做这样的事情:
if_nix gnu && alias ls='ls --color=auto' && export LS_COLORS="..."
if_nix bsd && export CLICOLORS=on && export LSCOLORS="..."
if_os linux && alias psg="ps -FA | grep" #alternative to pgrep
if_nix bsd && alias psg="ps -alwx | grep -i" #alternative to pgrep
if_os darwin && alias finder="open -R"