Windows/CygwinとMacおよびLinuxの両方で使用されるシェルスクリプトがあります。バージョンごとにわずかに異なる変数が必要です。
Shell/bashスクリプトは、Cygwin、Mac、またはLinuxで実行されているかどうかをどのように検出できますか?
通常、uname
にはさまざまなオプションがあり、実行している環境がわかります。
pax> uname -a
CYGWIN_NT-5.1 IBM-L3F3936 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin
pax> uname -s
CYGWIN_NT-5.1
そして、非常に役立つschot
(コメント内)によれば、uname -s
はOSXの場合はDarwin
を、Linuxの場合はLinux
を提供しますが、私のCygwinはCYGWIN_NT-5.1
を提供します。ただし、あらゆる種類の異なるバージョンを試す必要がある場合があります。
したがって、このようなチェックを行うbash
コードは、次の行に沿ったものになります。
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
echo ${machine}
ここでは、実際にwithin CygWin(そのbash
Shell)を実行していると仮定しているため、パスは既に正しく設定されているはずです。 1人のコメント者が指摘しているように、bash
プログラムを実行して、cmd
自体からスクリプトを渡すと、必要に応じてパスが設定されない可能性があります。
areを実行している場合、パスを事前に変更するか、実行可能ファイルの場所(/c/cygwin/bin/uname
など)を完全に指定することにより、正しい実行可能ファイル(つまり、CygWinの実行可能ファイル)が呼び出されるようにするのはあなたの責任です。
#!/usr/bin/env bash
の代わりに#!/bin/sh
を使用して、異なるプラットフォームの異なるデフォルトシェルにリンクされた/bin/sh
によって引き起こされる問題を回避します。そうしないと、unexpected operator、それが私のコンピューターで起こったことです(Ubuntu 64ビット12.04)。expr
プログラムがありません。そのため、単にuname
を使用します。uname
を使用して、システム情報(-s
パラメーター)を取得します。expr
およびsubstr
を使用して、文字列を処理します。if
Elif
fi
を使用して、一致するジョブを実行します。uname -s
仕様に従ってください。#!/usr/bin/env bash
if [ "$(uname)" == "Darwin" ]; then
# Do something under Mac OS X platform
Elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
# Do something under GNU/Linux platform
Elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then
# Do something under 32 bits Windows NT platform
Elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
# Do something under 64 bits Windows NT platform
fi
uname -s
(--kernel-name
)を使用するのは、uname -o
(--operating-system
)がサポートされていないためですMac OS、Solarisなどの一部のオペレーティングシステム。デフォルト引数が-s
(--kernel-name
)であるため、引数なしでuname
のみを使用することもできます。
以下のスニペットは bash を必要としません(つまり_#!/bin/bash
は必要ありません)
#!/bin/sh
case "$(uname -s)" in
Darwin)
echo 'Mac OS X'
;;
Linux)
echo 'Linux'
;;
CYGWIN*|MINGW32*|MSYS*)
echo 'MS Windows'
;;
# Add here more strings to compare
# See correspondence table at the bottom of this answer
*)
echo 'other OS'
;;
esac
以下のMakefile
は Gitプロジェクト(config.mak.uname
) から着想を得たものです。
ifdef MSVC # Avoid the MingW/Cygwin sections
uname_S := Windows
else # If uname not available => 'not'
uname_S := $(Shell sh -c 'uname -s 2>/dev/null || echo not')
endif
# Avoid nesting "if .. else if .. else .. endif endif"
# because maintenance of matching if/else/endif is a pain
ifeq ($(uname_S),Windows)
CC := cl
endif
ifeq ($(uname_S),OSF1)
CFLAGS += -D_OSF_SOURCE
endif
ifeq ($(uname_S),Linux)
CFLAGS += -DNDEBUG
endif
ifeq ($(uname_S),GNU/kFreeBSD)
CFLAGS += -D_BSD_ALLOC
endif
ifeq ($(uname_S),UnixWare)
CFLAGS += -Wextra
endif
...
uname -s
およびMakefile
に関するこの完全な回答 も参照してください。
この回答の下部にある対応表は、 uname
に関するウィキペディアの記事 からのものです。最新の状態に保つために貢献してください(回答を編集するか、コメントを投稿してください)。また、Wikipediaの記事を更新し、コメントを投稿して、あなたの貢献について通知してください;-)
Operating System
uname -s
Mac OS X
Darwin
Cygwin 32-bit (Win-XP)
CYGWIN_NT-5.1
Cygwin 32-bit (Win-7 32-bit)
CYGWIN_NT-6.1
Cygwin 32-bit (Win-7 64-bit)
CYGWIN_NT-6.1-WOW64
Cygwin 64-bit (Win-7 64-bit)
CYGWIN_NT-6.1
MinGW (Windows 7 32-bit)
MINGW32_NT-6.1
MinGW (Windows 10 64-bit)
MINGW64_NT-10.0
Interix (Services for UNIX)
Interix
MSYS
MSYS_NT-6.1
Windows Subsystem for Linux
Linux
Android
Linux
coreutils
Linux
CentOS
Linux
Fedora
Linux
Gentoo
Linux
Red Hat Linux
Linux
Linux Mint
Linux
openSUSE
Linux
Ubuntu
Linux
Unity Linux
Linux
Manjaro Linux
Linux
OpenWRT r40420
Linux
Debian (Linux)
Linux
Debian (GNU Hurd)
GNU
Debian (kFreeBSD)
GNU/kFreeBSD
FreeBSD
FreeBSD
NetBSD
NetBSD
DragonFlyBSD
DragonFly
Haiku
Haiku
NonStop
NONSTOP_KERNEL
QNX
QNX
ReliantUNIX
ReliantUNIX-Y
SINIX
SINIX-Y
Tru64
OSF1
Ultrix
ULTRIX
IRIX 32 bits
IRIX
IRIX 64 bits
IRIX64
MINIX
Minix
Solaris
SunOS
UWIN (64-bit Windows 7)
UWIN-W7
SYS$UNIX:SH on OpenVMS
IS/WB
z/OS USS
OS/390
Cray
sn5176
(SCO) OpenServer
SCO_SV
(SCO) System V
SCO_SV
(SCO) UnixWare
UnixWare
IBM AIX
AIX
IBM i with QSH
OS400
HP-UX
HP-UX
Bashは、シェル変数OSTYPEを設定します。 man bash
から:
Bashが実行されているオペレーティングシステムを説明する文字列に自動的に設定されます。
これは、uname
よりも小さな利点があり、新しいプロセスを起動する必要がないため、実行がより速くなります。
しかし、期待される値の信頼できるリストを見つけることができません。 Ubuntu 14.04の場合、「linux-gnu」に設定されています。私は他の価値のためにウェブをこすりました。したがって:
case "$OSTYPE" in
linux*) echo "Linux / WSL" ;;
darwin*) echo "Mac OS" ;;
win*) echo "Windows" ;;
msys*) echo "MSYS / MinGW / Git Bash" ;;
cygwin*) echo "Cygwin" ;;
bsd*) echo "BSD" ;;
solaris*) echo "Solaris" ;;
*) echo "unknown: $OSTYPE" ;;
esac
アスタリスクは重要な場合があります。たとえば、OSXは「darwin」の後にOSバージョン番号を追加します。 「win」の値は実際には「win32」ですが、「win64」があるのでしょうか?
おそらく、ここで検証済みの値のテーブルを作成するために協力することができます
linux-gnu
cygwin
msys
(既存のエントリと異なる場合は、値を追加してください)
アルバートの答えに基づいて、Windowsの検出に$COMSPEC
を使用するのが好きです。
#!/bin/bash
if [ "$(uname)" == "Darwin" ]
then
echo Do something under Mac OS X platform
Elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]
then
echo Do something under Linux platform
Elif [ -n "$COMSPEC" -a -x "$COMSPEC" ]
then
echo $0: this script does not support Windows \:\(
fi
これにより、$OS
のWindows名のバリアントの解析、およびMINGW、Cygwinなどのuname
のバリアントの解析が回避されます。
背景:%COMSPEC%
は、コマンドプロセッサ(別名Windowsシェル)へのフルパスを指定するWindows環境変数です。この変数の値は通常%SystemRoot%\system32\cmd.exe
であり、通常はC:\Windows\system32\cmd.exe
に評価されます。
# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
echo Cygwin rulez
else
echo Unix is king
fi
Uname -sコマンドの最初の6文字が「CYGWIN」の場合、cygwinシステムが想定されます
http://en.wikipedia.org/wiki/Uname
必要なすべての情報。 Googleはあなたの友達です。
uname -s
を使用して、システム名を照会します。
Darwin
CYGWIN_...
LINUX
OK、これが私のやり方です。
osis()
{
local n=0
if [[ "$1" = "-n" ]]; then n=1;shift; fi
# echo $OS|grep $1 -i >/dev/null
uname -s |grep -i "$1" >/dev/null
return $(( $n ^ $? ))
}
例えば.
osis Darwin &&
{
log_debug Detect mac osx
}
osis Linux &&
{
log_debug Detect linux
}
osis -n Cygwin &&
{
log_debug Not Cygwin
}
これを dotfiles で使用します
この質問が行われたとき、Linux用のWindowsサブシステムは存在しませんでした。私のテストでは次の結果が得られました。
uname -s -> Linux
uname -o -> GNU/Linux
uname -r -> 4.4.0-17763-Microsoft
これは、ネイティブLinuxと区別するためにuname -rが必要であることを意味します。
Unameの答えは、主に清潔さの点で無敵だと思います。
実行にはとんでもない時間がかかりますが、実行可能ファイルを呼び出さないので、特定のファイルが存在するかどうかをテストすることで、良好で迅速な結果が得られることがわかりました。
そう、
[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running
簡単なBashファイルの存在チェックを使用するだけです。現在Windowsを使用しているので、LinuxとMac OS Xの特定のファイルを頭から話すことはできませんが、それらが存在することは間違いありません。 :-)