web-dev-qa-db-ja.com

Cygwin、MacまたはLinuxで実行されているかどうかを確認する方法は?

Windows/CygwinとMacおよびLinuxの両方で使用されるシェルスクリプトがあります。バージョンごとにわずかに異なる変数が必要です。

Shell/bashスクリプトは、Cygwin、Mac、またはLinuxで実行されているかどうかをどのように検出できますか?

272
bastibe

通常、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の実行可能ファイル)が呼び出されるようにするのはあなたの責任です。

239
paxdiablo

3つの異なるOSタイプ(GNU/Linux、Mac OS X、Windows NT)を検出するために使用したbashスクリプトは次のとおりです。

注意を払う

  • Bashスクリプトで、#!/usr/bin/env bashの代わりに#!/bin/shを使用して、異なるプラットフォームの異なるデフォルトシェルにリンクされた/bin/shによって引き起こされる問題を回避します。そうしないと、unexpected operator、それが私のコンピューターで起こったことです(Ubuntu 64ビット12.04)。
  • Mac OS X 10.6.8(Snow Leopard)には、インストールしない限りexprプログラムがありません。そのため、単にunameを使用します。

設計

  1. unameを使用して、システム情報(-sパラメーター)を取得します。
  2. exprおよびsubstrを使用して、文字列を処理します。
  3. ifEliffiを使用して、一致するジョブを実行します。
  4. 必要に応じて、システムサポートを追加できます。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

テスト中

  • Linux(Ubuntu 12.04 LTS、Kernel 3.2.0)はテスト済みです。
  • OS X(10.6.8 Snow Leopard)は正常にテストされました。
  • Windows(Windows 7 64ビット)は正常にテストされました。

学んだこと

  1. 開始引用符と終了引用符の両方を確認してください。
  2. 欠落している括弧と中括弧を確認してください{}

参照資料

290
Albert

uname -s--kernel-name)を使用するのは、uname -o--operating-system)がサポートされていないためですMac OSSolarisなどの一部のオペレーティングシステム。デフォルト引数が-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

以下のMakefileGitプロジェクト(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 Systemuname -s
Mac OS XDarwin
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)InterixMSYSMSYS_NT-6.1Windows Subsystem for LinuxLinux
AndroidLinux
coreutilsLinux
CentOSLinux
FedoraLinux
GentooLinux
Red Hat LinuxLinux
Linux MintLinux
openSUSELinux
UbuntuLinux
Unity LinuxLinux
Manjaro LinuxLinux
OpenWRT r40420Linux
Debian (Linux)Linux
Debian (GNU Hurd)GNU
Debian (kFreeBSD)GNU/kFreeBSD
FreeBSDFreeBSD
NetBSDNetBSD
DragonFlyBSDDragonFly
HaikuHaiku
NonStopNONSTOP_KERNEL
QNXQNX
ReliantUNIXReliantUNIX-Y
SINIXSINIX-Y
Tru64OSF1
UltrixULTRIX
IRIX 32 bitsIRIX
IRIX 64 bitsIRIX64
MINIXMinix
SolarisSunOS
UWIN (64-bit Windows 7)UWIN-W7
SYS$UNIX:SH on OpenVMSIS/WB
z/OS USSOS/390
Craysn5176
(SCO) OpenServerSCO_SV
(SCO) System VSCO_SV
(SCO) UnixWareUnixWare
IBM AIXAIX
IBM i with QSHOS400
HP-UXHP-UX

95
olibre

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 Ubuntu(含む WSL ):linux-gnu
  • Cygwin 64ビット:cygwin
  • Msys/MINGW(Git Bash for Windows):msys

(既存のエントリと異なる場合は、値を追加してください)

58

アルバートの答えに基づいて、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に評価されます。

9
Steve Jansen
# 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システムが想定されます

8
Jan Helge

http://en.wikipedia.org/wiki/Uname

必要なすべての情報。 Googleはあなたの友達です。

uname -sを使用して、システム名を照会します。

  • Mac:Darwin
  • Cygwin:CYGWIN_...
  • Linux:さまざま、ほとんどの場合LINUX
3
rubenvb

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 で使用します

1
wener

この質問が行われたとき、Linux用のWindowsサブシステムは存在しませんでした。私のテストでは次の結果が得られました。

uname -s -> Linux
uname -o -> GNU/Linux
uname -r -> 4.4.0-17763-Microsoft

これは、ネイティブLinuxと区別するためにuname -rが必要であることを意味します。

0
A Fog

Unameの答えは、主に清潔さの点で無敵だと思います。

実行にはとんでもない時間がかかりますが、実行可能ファイルを呼び出さないので、特定のファイルが存在するかどうかをテストすることで、良好で迅速な結果が得られることがわかりました。

そう、

[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running

簡単なBashファイルの存在チェックを使用するだけです。現在Windowsを使用しているので、LinuxとMac OS Xの特定のファイルを頭から話すことはできませんが、それらが存在することは間違いありません。 :-)