696

使用するすべてのコンピューター間でファイルを使用できるように、ファイルをバージョン管理.bashrcに保持したいと考えています。問題は、OS 固有のエイリアスがいくつかあるため、スクリプトが Mac OS X、Linux、またはCygwin.bash_loginで実行されているかどうかを判断する方法を探していたことです。

Bashスクリプトでオペレーティングシステムを検出する適切な方法は何ですか?

4

22 に答える 22

762

以下がうまくいくはずだと思います。よくわかりません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
于 2011-12-21T22:46:47.777 に答える
307

私の .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ます。

于 2008-12-26T20:36:15.140 に答える
291

bashのマンページによると、変数 OSTYPE にはオペレーティング システムの名前が格納されています。

OSTYPEbash が実行されているオペレーティング システムを説明する文字列に自動的に設定されます。デフォルトはシステムに依存します。

ここまで設定されてlinux-gnuいます。

于 2008-12-26T20:31:39.317 に答える
226

$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

ただし、古いシェル( Bourne shellなど) では認識されません。


uname

unameもう 1 つの方法は、コマンドに基づいてプラットフォームを検出することです。

次のスクリプトを参照してください (.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
于 2013-08-25T23:43:01.260 に答える
41

オペレーティング システムと CPU の種類を検出することは、ポータブルで行うのはそれほど簡単ではありません。私は、sh1988 年以来使用してきたさまざまな Unix プラットフォームで動作する約 100 行のスクリプトを持っています。

主な要素は次のとおりです。

  • uname -pプロセッサ タイプですが、通常unknownは最新の Unix プラットフォーム上にあります。

  • uname -m一部の Unix システムでは、「マシンのハードウェア名」が表示されます。

  • /bin/archが存在する場合、通常はプロセッサのタイプを示します。

  • uname引数を指定しないと、オペレーティング システムに名前が付けられます。

最終的には、プラットフォーム間の違いと、それらをどれだけ細かくしたいかについて考える必要があります. たとえば、単純にするために、 i386i686、任意の " Pentium*" および任意の " AMD*Athlon*" をすべて として扱いx86ます。

My~/.profileは起動時にスクリプトを実行し、1 つの変数を CPU とオペレーティング システムの組み合わせを示す文字列に設定します。それに基づいてセットアップされるプラットフォーム固有binの 、manlib、およびディレクトリがあります。include次に、大量の環境変数を設定しました。したがって、たとえば、メールを再フォーマットするシェル スクリプトは、たとえば、$LIB/mailfmtプラットフォーム固有の実行可能バイナリを呼び出すことができます。

手抜きしたい場合はuname -mplainunameが多くのプラットフォームで知りたいことを教えてくれます。必要に応じて他のものを追加します。(そしてcase、ネストされていない を使用してifください!)

于 2008-12-26T21:07:13.707 に答える
40

この完全な 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

于 2010-09-25T07:00:11.757 に答える
18

これらの答えのいくつかを避けることをお勧めします。他の形式の文字列比較を選択できることを忘れないでください。これにより、ほとんどのバリエーションや提供される醜いコードが解消されます。

そのような解決策の 1 つは、次のような単純なチェックです。

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

バージョンサフィックスにもかかわらず、Darwin のどのバージョンとも一致するという追加の利点があります。Linuxこれは、予想されるあらゆるバリエーションに対しても機能します。

ここのドットファイル内でいくつかの追加の例を見ることができます

于 2012-05-03T21:59:43.050 に答える
11

bash では、文書化されているよう$OSTYPEに andを使用します。$HOSTTYPEこれが私がすることです。それだけでは不十分で、unameor uname -a(または他の適切なオプション) でも十分な情報が得られない場合は、GNU プロジェクトのconfig.guessスクリプトが常にあり、この目的のために正確に作成されています。

于 2009-01-14T11:24:37.300 に答える
11

「うなめ」を使ってみてください。たとえば、Linux の場合: 「uname -a」。

マニュアルページによると、uname は SVr4 および POSIX に準拠しているため、Mac OS X およびCygwinでも使用できるはずですが、確認できません。

ところで: $OSTYPE もlinux-gnuここに設定されています:)

于 2008-12-26T20:33:03.493 に答える
10

私はこれらの砂糖を私の中に書きました.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"
于 2015-03-24T17:52:36.047 に答える
9
uname

また

uname -a

さらに情報が必要な場合

于 2008-12-26T20:33:45.363 に答える
8

私は、 GNUshtoolを使用してかなり正確なプラットフォーム検出を行う個人用のBashライブラリとスクリプトフレームワークを作成しました。

GNU shtoolは、非常に移植性の高いスクリプトのセットであり、特に「shtoolplatform」コマンドが含まれています。これが次の出力です。

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は少し遅いので、実際には、スクリプトが呼び出すシステム上のファイルにプラットフォームIDを保存して更新します。それは私のフレームワークなので、それは私にとってはうまくいきますが、あなたのマイレージは異なるかもしれません。

ここで、スクリプトと一緒にshtoolをパッケージ化する方法を見つける必要がありますが、それは難しい作業ではありません。また、uname出力にいつでもフォールバックできます。

編集:

テディの投稿をconfig.guess(どういうわけか)見逃しました。これらは非常によく似たスクリプトですが、同じではありません。私は個人的にshtoolを他の用途にも使用していますが、それは私にとって非常にうまく機能しています。

于 2009-03-12T19:15:28.040 に答える
-1

次のことを行うと、ubuntu のチェックを正しく実行するのに役立ちました。

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi
于 2013-08-21T01:53:56.960 に答える