如何从 Bash 脚本中检测操作系统?

Posted

技术标签:

【中文标题】如何从 Bash 脚本中检测操作系统?【英文标题】:How to detect the OS from a Bash script? 【发布时间】:2010-09-28 11:56:21 【问题描述】:

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

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

【问题讨论】:

你有没有考虑过分享你的配置?我正在寻找相同的设置:) @sorin 我知道这是一条旧评论,但如果您仍然好奇,我一直在构建 ProfileGem,它可以让您为所有机器配置可插入的 bash 环境。 @dimo414 profilegem 似乎已移至此处bitbucket.org/dimo414/profilegem。至于一般共享 bash 配置,请尝试其中一些 dotfiles 项目:github.com/… @mahemoff 感谢更新链接,抱歉我无法编辑我的评论。如果您正在试用 ProfileGem,我欢迎您提供反馈或错误! 唉 BitBucket 正在拒绝 Mercurial 支持,所以我必须再次更新我的链接 :( github.com/dimo414/ProfileGem 是新家。 【参考方案1】:

bash manpage 表示变量 OSTYPE 存储操作系统的名称:

OSTYPE 自动设置为描述执行 bash 的操作系统的字符串。默认是系统- 依赖。

这里设置为linux-gnu

【讨论】:

另外,$OSTYPE 在我的 mac (Leopard) 上是“darwin9.0”,在 Cygwin 下是“cygwin”。 $OSTYPE 在 SnowLeopard 上是 darwin10.0。附加版本的WTF?意味着简单的 case 语句不起作用。 删除它没什么大不了的:os=$OSTYPE//[0-9.]/ case $OSTYPE in darwin*) echo I am a Mac ;; esac @tripleee 或对于更熟悉“if”语法的人:if [[ $OSTYPE == darwin* ]]; then echo I am a Mac;fi【参考方案2】:

尝试使用“uname”。例如,在 Linux 中:“uname -a”。

根据手册页,uname 符合 SVr4 和 POSIX,因此它应该可以在 Mac OS X 和 Cygwin 上使用,但我无法确认。

顺便说一句:这里 $OSTYPE 也设置为 linux-gnu :)

【讨论】:

没有参数,uname 在 Mac OS X (leopard) 上打印 'Darwin'。使用 -a 它会打印大量额外信息(内核版本、架构和其他我无法解读的信息)。我无法在 cygwin 上测试【参考方案3】:
uname

uname -a

如果您想了解更多信息

【讨论】:

【参考方案4】:

对于我的 .bashrc,我使用以下代码:

platform='unknown'
unamestr=$(uname)
if [[ "$unamestr" == 'Linux' ]]; then
   platform='linux'
elif [[ "$unamestr" == 'FreeBSD' ]]; then
   platform='freebsd'
fi

然后我会做类似的事情:

if [[ $platform == 'linux' ]]; then
   alias ls='ls --color=auto'
elif [[ $platform == 'freebsd' ]]; then
   alias ls='ls -G'
fi

它很丑,但它有效。如果您愿意,可以使用case 代替if

【讨论】:

为什么要从 unamestr 设置平台,而不是只使用 unamestr? 不要使用反引号,使用更新更清晰的语法:“unamestr = $(uname)”。 乍一看,反引号可能类似于字符串。 @david-winiecki 因为如果您需要嵌套命令,例如$(command-1 $(command-2)) 这样做不是更好吗:platform="$(uname | tr '[:upper:]' '[:lower:]')" 然后肯定处理一个案例?硬编码对特定输出的依赖似乎很奇怪。【参考方案5】:

检测操作系统和 CPU 类型并不是那么容易便携。我有一个大约 100 行的 sh 脚本,它适用于各种 Unix 平台:我自 1988 年以来使用的任何系统。

关键要素是

uname -p处理器类型,但在现代 Unix 平台上通常是 unknown

uname -m 将在某些 Unix 系统上给出“机器硬件名称”。

/bin/arch,如果存在,通常会给出处理器的类型。

uname 不带参数将命名操作系统。

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

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

如果你想偷工减料uname -m 和普通的uname 会在许多平台上告诉你你想知道什么。需要时添加其他内容。 (并使用case,而不是嵌套if!)

【讨论】:

根据uname Command的说法,不带参数的uname相当于使用“-s”参数:“-s 显示系统名称。该标志默认开启."。明确地说,可以使用“uname -s”而不是“uname”。 (在 an answer to 'Shell output help' 中有所阐述) 你是否有一个 github git 或 pastebin 的链接以及这个 100 脚本以可靠地检测操作系统和处理器架构? @AndrewDeAndrade 我很惭愧将这段代码公开。 pastebin.com/J66Lj6wf 那么uname -s呢?【参考方案6】:

在 bash 中,使用 $OSTYPE$HOSTTYPE,如文档所述;这就是我所做的。如果这还不够,并且即使 unameuname -a(或其他适当的选项)也没有提供足够的信息,那么 GNU 项目中总会有 config.guess 脚本,正是为此目的而制作的。

【讨论】:

【参考方案7】:

我写了a personal Bash library and scripting framework,它使用GNU shtool 来进行相当准确的平台检测。

GNU shtool 是一组非常便携的脚本,其中包含“shtool platform”命令等有用的东西。这是输出:

shtool platform -v -F "%sc (%ac) %st (%at) %sp (%ap)"

在几台不同的机器上:

Mac OS X Leopard: 
    4.4BSD/Mach3.0 (iX86) Apple Darwin 9.6.0 (i386) Apple Mac OS X 10.5.6 (iX86)

Ubuntu Jaunty server:
    LSB (iX86) GNU/Linux 2.9/2.6 (i686) Ubuntu 9.04 (iX86)

Debian Lenny:
    LSB (iX86) GNU/Linux 2.7/2.6 (i686) Debian GNU/Linux 5.0 (iX86)

如您所见,这会产生非常令人满意的结果。 GNU shtool 有点慢,所以我实际上在我的脚本调用的系统上的一个文件中存储和更新平台标识。这是我的框架,所以它适用于我,但你的里程可能会有所不同。

现在,您必须找到一种方法将 shtool 与您的脚本打包在一起,但这并不是一项艰巨的练习。您也可以随时使用 uname 输出。

编辑:

我错过了 Teddy 关于config.guess 的帖子(不知何故)。这些是非常相似的脚本,但并不相同。我个人也将 shtool 用于其他用途,它对我来说效果很好。

【讨论】:

【参考方案8】:

我推荐使用这个完整的 bash 代码

lowercase()
    echo "$1" | 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 $2 '`
            PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F=  ' print $2 '`
            REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F=  ' print $2 '`
        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
echo $OS
echo $KERNEL
echo $MACH

更多示例:https://github.com/coto/server-easy-install/blob/master/lib/core.sh

【讨论】:

你遗漏了小写函数,我为你更新了答案。 一旦你知道它是 Linux,如果你只是四处寻找(而不是试图自动找出),似乎最简单的举动就是 ls /etc 并寻找“blah-release” - 不管废话,那就是 Linux 操作系统 - CentOS、Ubuntu 等 我进行了编辑,因为一些对 OS 变量的引用被写为“$OS”我将它们更改为“$OS”,这是正确的方法,我测试了它 您会考虑在脚本的最后添加“echo $OS”吗? 这对于最后的一个大谜团来说是很多工作(没有打印信息)。我认为它最后需要echo $OS【参考方案9】:

我认为以下应该有效。不过我不确定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

【讨论】:

在 Windows 上,Git Bash/msysGit 将获得 msys,Cygwin 将获得 cygwin 这个包括如何检测 Windows 的答案很好。我也在使用 Mingw32,它显示为 msys 有趣.. Mac OSX 仍然会给出 'darwin'。 当你用命令替换评论时让我感到困惑的事情 - 确保以 ; 结尾。 当我添加像source somefile ; 这样的命令时,我得到syntax error near unexpected token elif【参考方案10】:

我建议避免其中一些答案。不要忘记您可以选择其他形式的字符串比较,这样可以清除大部分变体或提供的丑陋代码。

一个这样的解决方案是一个简单的检查,例如:

if [[ "$OSTYPE" =~ ^darwin ]]; then

它具有匹配任何版本的达尔文的额外好处,尽管它的版本后缀。这也适用于人们可能期望的Linux 的任何变体。

您可以在我的点文件here中看到一些其他示例

【讨论】:

【参考方案11】:

执行以下操作有助于正确执行 ubuntu 的检查:

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

【讨论】:

其他不使用apt-get的Linux系统呢? ubuntu 是一个发行版,而不是一个操作系统类。【参考方案12】:

$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

不过是not recognized by the older shells(比如Bourne shell)。


uname

另一种方法是基于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

You can find some practical example in my .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

【讨论】:

$OSTYPE 检查缺少 cygwin 的分支,这表明是 Windows 机器。 uname 检查也无法正常工作,在 cygwin 上 uname 返回“CYGWIN_NT-10.0”,在 MinGW 上 uname 返回“MINGW64_NT-10.0”。 alias ls='/bin/ls -G' 实际上是安全的选择,在基于操作系统的 fags 的上下文中,请参阅superuser.com/a/1299969/84662 我建议使用uname,Oracle 已经修改了约定,并在其OSTYPE ==&gt; solaris2.11 中放置了一个免费版本字符串。 uname 更干净一些,工作量也更少。【参考方案13】:

这应该可以在所有发行版上安全使用。

$ cat /etc/*release

这会产生类似的东西。

     DISTRIB_ID=LinuxMint
     DISTRIB_RELEASE=17
     DISTRIB_CODENAME=qiana
     DISTRIB_DESCRIPTION="Linux Mint 17 Qiana"
     NAME="Ubuntu"
     VERSION="14.04.1 LTS, Trusty Tahr"
     ID=ubuntu
     ID_LIKE=debian
     PRETTY_NAME="Ubuntu 14.04.1 LTS"
     VERSION_ID="14.04"
     HOME_URL="http://www.ubuntu.com/"
     SUPPORT_URL="http://help.ubuntu.com/"
     BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

根据需要提取/分配给变量

注意:在某些设置上。这也可能会给您一些可以忽略的错误。

     cat: /etc/upstream-release: Is a directory

【讨论】:

注意:在 CentOS 上,这给出了[user@host ~]$ cat /etc/*release CentOS release 6.4 (Final) CentOS release 6.4 (Final) CentOS release 6.4 (Final) 是的,我发布的输出是一个示例,来自我的一台笔记本电脑,而不是随处可见的静态内容。 刚刚添加,所以没有人会认为结果总是相同的形式:) +1 我在脚本的开头使用了 set -e (因此这个解决方案不起作用doxer.org/linux-shell-centos-debian-ostype)。而其他解决方案并不专门针对 CentOS。但我发现这个参考证明了这个答案unix.stackexchange.com/a/92212 不适用于 Mac:cat: /etc/*release: No such file or directory【参考方案14】:

我倾向于将我的 .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 做同样的事情

【讨论】:

【参考方案15】:

我在.bashrc 中写了这些糖:

if_os ()  [[ $OSTYPE == *$1* ]]; 
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" == "$1" ]];

所以我可以这样做:

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"

【讨论】:

顺便说一句,这 9 行代码适用于运行在几乎任何东西上的任何 Bash。没有外壳,几乎可以与任何风格的个人 .bashrc 一起使用(大的嵌套 if/case 树或许多随机别名)。国际海事组织,击败上面的每个答案。 到目前为止,最接近完成的包括 Cygwin 和其他 BSD(基本上是流行的 *NIX 的编译) 对于今天相关并运行 Bash 的用户空间完成。 AIX/HP-UX/IRIX/OpenVMS 用户可以加入。适用于 Linux 的新 Windows 子系统运行库存的 amd64 Ubuntu 安装,因此对于 if_nix gnuif_os linux 都应该返回 true。 @kfix 是的,没错,win 10 bash 子系统为echo $OSTYPE 输出“linux-gnu”。要专门检测 win 10 bash 子系统,我发现的唯一解决方案是在/proc/sys/kernel/osrelease中检查“Microsoft”@【参考方案16】:

您可以使用以下 if 子句并根据需要对其进行扩展:

if [ "$OSTYPE//[0-9.]/" == "darwin" ]
then
    aminute_ago="-v-1M"
elif  [ "$OSTYPE//[0-9.]/" == "linux-gnu" ]
then
    aminute_ago="-d \"1 minute ago\""
fi

【讨论】:

【参考方案17】:

下面是一种利用 /etc/lsb-release 检测基于 Debian 和 RedHat 的 Linux 操作系统 的方法/etc/os-release(取决于您使用的 Linux 风格)并根据它采取简单的操作。

#!/bin/bash
set -e

YUM_PACKAGE_NAME="python python-devl python-pip openssl-devel"
DEB_PACKAGE_NAME="python2.7 python-dev python-pip libssl-dev"

 if cat /etc/*release | grep ^NAME | grep CentOS; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on CentOS"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Red; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on RedHat"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Fedora; then
    echo "================================================"
    echo "Installing packages $YUM_PACKAGE_NAME on Fedorea"
    echo "================================================"
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Ubuntu; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Ubuntu"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Debian ; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Debian"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Mint ; then
    echo "============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Mint"
    echo "============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Knoppix ; then
    echo "================================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Kanoppix"
    echo "================================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 else
    echo "OS NOT DETECTED, couldn't install package $PACKAGE"
    exit 1;
 fi

exit 0
Ubuntu Linux 的

输出示例

delivery@delivery-E5450$ sudo sh detect_os.sh
[sudo] password for delivery: 
NAME="Ubuntu"
===============================================
Installing packages python2.7 python-dev python-pip libssl-dev on Ubuntu
===============================================
Ign http://dl.google.com stable InRelease
Get:1 http://dl.google.com stable Release.gpg [916 B]                          
Get:2 http://dl.google.com stable Release [1.189 B] 
...            

【讨论】:

【参考方案18】:

我在几个 Linux 发行版中尝试了上述消息,发现以下消息最适合我。这是一个简短、准确的单词答案,也适用于 Windows 上的 Bash。

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu

【讨论】:

虽然欢迎使用此代码 sn-p,并且可能会提供一些帮助,但它会是 howwhy 的 greatly improved if it included an explanation 这解决了问题。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。 对于大多数 linux 系统来说看起来不错且简洁,但不幸的是这会导致 macOS 上的错误。也许这更像是“从 Bash 检测 linux 发行版的味道 @csexton OS=$( ([[ -f /etc/*release ]] &amp;&amp; cat /etc/*release | grep ^NAME | tr -d 'NAME="') || echo "Unknown" ) 这将工作而不会引发错误。 其实这里有一个正确的方法OS=$( $(compgen -G "/etc/*release" &gt; /dev/null) &amp;&amp; cat /etc/*release | grep ^NAME | tr -d 'NAME="') || $( echo "$OSTYPE//[0-9.]/") @Kuzeko 不幸的是,我在 macOS 上运行它仍然会出错。【参考方案19】:

您可以使用以下内容:

OS=$(uname -s)

那么您可以在脚本中使用 OS 变量。

【讨论】:

您能解释一下uname -suname 的不同之处吗? @AlexanderMills -s, --kernel-name 打印内核名称【参考方案20】:

这会检查一堆 known 文件以识别 linux 发行版是 Debian 还是 Ubunu,然后它默认为 $OSTYPE 变量。

os='Unknown'
unamestr="$OSTYPE//[0-9.]/"
os=$( compgen -G "/etc/*release" > /dev/null  && cat /etc/*release | grep ^NAME | tr -d 'NAME="'  ||  echo "$unamestr")

echo "$os"

【讨论】:

【参考方案21】:

试试这个:

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

【讨论】:

在 macOS 上我得到cat: /etc/*-release: No such file or directory @csexton 真的,我也一样:zsh: no matches found: /etc/*release——我想这仅适用于 linux 系统... 这个答案肯定只适用于 Linux。但其他答案只能检测与其他系统相反的 Linux。这个基本发现对于发现特定的 Linux 发行版根本没有帮助,就像区分 FreeBSD 和 Darwin 一样重要。 好的,当我发布此评论时,无需针对多个平台执行此操作,因此我尝试展示如何查看您的 Linux 发行版 :) 这个管道符号用的真漂亮!【参考方案22】:

如果有人也对检测 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;

【讨论】:

以上是关于如何从 Bash 脚本中检测操作系统?的主要内容,如果未能解决你的问题,请参考以下文章

检测 NODE.JS 脚本是通过 bash(unix)/cmd(windows)直接调用还是导入(ESM 模块加载器)[重复]

如何检测我运行 shell 脚本的当前目录?

从 bash 脚本检测“Windows 上的 Ubuntu”与本机 Ubuntu [重复]

如何从脚本本身中获取 Bash 脚本的源目录?

如何从脚本本身中获取 Bash 脚本的源目录?

如何从 bash 脚本中 ssh?