使用するすべてのコンピューター間でファイルを使用できるように、ファイルをバージョン管理.bashrc
に保持したいと考えています。問題は、OS 固有のエイリアスがいくつかあるため、スクリプトが Mac OS X、Linux、またはCygwin.bash_login
で実行されているかどうかを判断する方法を探していたことです。
Bashスクリプトでオペレーティングシステムを検出する適切な方法は何ですか?
使用するすべてのコンピューター間でファイルを使用できるように、ファイルをバージョン管理.bashrc
に保持したいと考えています。問題は、OS 固有のエイリアスがいくつかあるため、スクリプトが Mac OS X、Linux、またはCygwin.bash_login
で実行されているかどうかを判断する方法を探していたことです。
Bashスクリプトでオペレーティングシステムを検出する適切な方法は何ですか?
以下がうまくいくはずだと思います。よくわかりません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
私の .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
ます。
bashのマンページによると、変数 OSTYPE にはオペレーティング システムの名前が格納されています。
OSTYPE
bash が実行されているオペレーティング システムを説明する文字列に自動的に設定されます。デフォルトはシステムに依存します。
ここまで設定されてlinux-gnu
います。
$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
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
オペレーティング システムと CPU の種類を検出することは、ポータブルで行うのはそれほど簡単ではありません。私は、sh
1988 年以来使用してきたさまざまな Unix プラットフォームで動作する約 100 行のスクリプトを持っています。
主な要素は次のとおりです。
uname -p
プロセッサ タイプですが、通常unknown
は最新の Unix プラットフォーム上にあります。
uname -m
一部の Unix システムでは、「マシンのハードウェア名」が表示されます。
/bin/arch
が存在する場合、通常はプロセッサのタイプを示します。
uname
引数を指定しないと、オペレーティング システムに名前が付けられます。
最終的には、プラットフォーム間の違いと、それらをどれだけ細かくしたいかについて考える必要があります. たとえば、単純にするために、 i386
~i686
、任意の " Pentium*
" および任意の " AMD*Athlon*
" をすべて として扱いx86
ます。
My~/.profile
は起動時にスクリプトを実行し、1 つの変数を CPU とオペレーティング システムの組み合わせを示す文字列に設定します。それに基づいてセットアップされるプラットフォーム固有bin
の 、man
、lib
、およびディレクトリがあります。include
次に、大量の環境変数を設定しました。したがって、たとえば、メールを再フォーマットするシェル スクリプトは、たとえば、$LIB/mailfmt
プラットフォーム固有の実行可能バイナリを呼び出すことができます。
手抜きしたい場合は、uname -m
plainuname
が多くのプラットフォームで知りたいことを教えてくれます。必要に応じて他のものを追加します。(そしてcase
、ネストされていない を使用してif
ください!)
この完全な 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
これらの答えのいくつかを避けることをお勧めします。他の形式の文字列比較を選択できることを忘れないでください。これにより、ほとんどのバリエーションや提供される醜いコードが解消されます。
そのような解決策の 1 つは、次のような単純なチェックです。
if [[ "$OSTYPE" =~ ^darwin ]]; then
バージョンサフィックスにもかかわらず、Darwin のどのバージョンとも一致するという追加の利点があります。Linux
これは、予想されるあらゆるバリエーションに対しても機能します。
ここのドットファイル内でいくつかの追加の例を見ることができます
bash では、文書化されているよう$OSTYPE
に andを使用します。$HOSTTYPE
これが私がすることです。それだけでは不十分で、uname
or uname -a
(または他の適切なオプション) でも十分な情報が得られない場合は、GNU プロジェクトのconfig.guessスクリプトが常にあり、この目的のために正確に作成されています。
「うなめ」を使ってみてください。たとえば、Linux の場合: 「uname -a」。
マニュアルページによると、uname は SVr4 および POSIX に準拠しているため、Mac OS X およびCygwinでも使用できるはずですが、確認できません。
ところで: $OSTYPE もlinux-gnu
ここに設定されています:)
私はこれらの砂糖を私の中に書きました.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"
uname
また
uname -a
さらに情報が必要な場合
私は、 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を他の用途にも使用していますが、それは私にとって非常にうまく機能しています。
次のことを行うと、ubuntu のチェックを正しく実行するのに役立ちました。
if [[ "$OSTYPE" =~ ^linux ]]; then
sudo apt-get install <some-package>
fi