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


334

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

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

回答:


322

通常、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与えDarwinOSX用とLinux私のCygwinは与えながら、Linux用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}

ここでは実際 CygWin(そのbashシェル)内で実行していると想定しているため、パスはすでに正しく設定されているはずです。あるコメンターが注記しているように、bashプログラムを実行してスクリプトを渡すことができます。cmdこれにより、必要に応じてパスが設定されない可能性があります。

その場合、おそらく事前にパスを変更するか、実行可能ファイルの場所(たとえば/c/cygwin/bin/uname)を完全に指定して、正しい実行可能ファイル(CygWinなど)が呼び出されていることを確認する必要があります。


11
時には、以下よりです;)ところで、ウィキペディアがで例のuname出力のテーブルがあるen.wikipedia.org/wiki/Uname
schot

Windows 7でのGit Bash uname -s出力はMINGW32_NT-6.1です。また、何も存在しない/cygdriveだけで、接頭辞/cのためにC:
ColinM、2011

7
Git BashはCygwinではありません。これはMinGW、MS Windowsの最小のGNUです。そのため、動作が異なります。
Boyd Stephen Smith Jr.

この回答はOPの部分How can a shell/bash script detect ...を扱っておらず、他の回答は扱っているため、他の回答を推奨しました。
ジェシーチザム2017

「\ cygwin64 \ bin \ bash -c scriptname」を実行してcygwinでスクリプトを実行すると、これは必ずしも機能しません。この状況では、cygwinパスは設定されず、現在のパスの最初にあるuname -sものを呼び出しunameます。これは、私のシステムgedaでは、テキストを返すインストールバージョンですWindowsNT。ただし、上記のMinGWバージョンでもかまいません。cygwinの信頼できる検出は、パスが適切に設定されているIMOに依存してはなりません。したがって、cygwinを検出する$(uname -s)ように変更する必要があります$(/bin/uname -s)
ジュール、

329

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

注意を払う

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

設計

  1. unameシステム情報(-sパラメーター)を取得するために使用します。
  2. 文字列を処理するには、exprand substrを使用します。
  3. if elif fiマッチングジョブを実行するために使用します。
  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、カーネル3.2.0)はテスト済みです。
  • OS X(10.6.8 Snow Leopard)はテスト済みです。
  • Windows(Windows 7 64ビット)でテスト済み。

私が学んだこと

  1. 開始と終了の両方の引用符を確認してください。
  2. 括弧と中括弧がないことを確認します{}

参考文献


MinGWの場合、以下を確認する方が理にかなっています[ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]
Achal Dave 2013

2
@アルバート:式"$(expr substr $(uname -s) 1 5)"は少し変です。これを行うには、もっときれいな方法がありますif [ `uname -s` == CYGWIN* ]; then。例:読む:CYGWINでuname -s始まる場合...
David FerenczyRogožan2014年

10
@DawidFerenczy私はそれはのような二重括弧が必要となると考えているif [[ $(uname -s) == CYGWIN* ]]; then
rogerdpack

1
質問で尋ねられたように、これはCygwinを検出しません。
rmcclellan

2
Linuxで最初の5文字のみをチェックするのはなぜですか?uname -s「Linux」以外のものが生成される最新のLinuxディストリビューションの例はありますか?
ktbiz 2016

127

使用uname -s--kernel-name)ので、uname -o--operating-system)などの一部のオペレーティングシステムでサポートされていませんマックOSおよびSolarisの。デフォルトの引数は()なので、uname引数なしで使用することもできます。-s--kernel-name

以下のスニペットは必要ありません (つまり、必要ありません#!/bin/bash

#!/bin/sh

case "$(uname -s)" in

   Darwin)
     echo 'Mac OS X'
     ;;

   Linux)
     echo 'Linux'
     ;;

   CYGWIN*|MINGW32*|MSYS*|MINGW*)
     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

この回答の下部にある対応表は、Wikipediaの記事からのものunameです。最新の状態に保つために貢献してください(回答を編集するか、コメントを投稿してください)。また、ウィキペディアの記事を更新し、コメントを投稿して、あなたの貢献について通知することもできます;-)

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
MSYS2 MSYS_NT-10.0-17763
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


3
Solarisと上記の研究に賛成です。
おくたね2017

@okutaneさん、こんにちは。あなたが何を言っているか理解できません。詳細を入力してください。何か提案はありますか?乾杯
olibre

3
私は投票しています、それだけです。
okutane 2017

1
これは、ポータブル/クロスプラットフォームを作成するために私が探していたものです~/.profile$PATH後世に検索キーワードを提供するためにコメントするような環境変数を設定するため)。
Braham Snyder

1
WSLを具体的に検出し、他のLinuxと区別したかったので、ここに来ました。そのとき私にとってうまくいくように見えるのは、以前にチェックuname -srして比較Linux*Microsoft)することLinux*)です。
einarmagnus

65

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

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


1
私はすでにあなたの答えが好きです。私がこれを必要としたまれな時期に完全に適合します
Charles Roberto Canato

6
技術的には、これは環境変数ではなく、シェル変数です。そのためenv | grep OSTYPE、の下には表示されませんが、下に表示されますset | grep OSTYPE
wisbucky

4
BashのOSTYPE変数(conftypes.h)は、ビルド時にautomakeのOS変数(Makefile.in)の正確なコピーを使用して構成されます。automakeのlib / config.subファイルで、利用可能なすべてのタイプを調べることができます。
jdknight 2017年

9

アルバートの答えに基づいて、私は$COMSPECWindowsの検出に使用するのが好きです:

#!/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

これにより、のWindows名の$OSバリアントの解析、およびuname、MINGW、Cygwinなどの。

背景:%COMSPEC%コマンドプロセッサ(Windowsシェルとも呼ばれます)への完全パスを指定するWindows環境変数です。この変数の値は通常%SystemRoot%\system32\cmd.exeであり、通常はに評価されC:\Windows\system32\cmd.exeます。


Windows UWS Bash環境で実行するときに$ COMSPECが設定されていないため、これ以上は修正しないでください。
ジュリアンナイト

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


if [ `uname -s` == CYGWIN* ]; then見栄えがよく、同じように動作します。
David FerenczyRogožan2014年

6
はい、ただし二重括弧を使用します[[ $(uname -s) == CYGWIN* ]]。また、拡張正規表現の方が私たちのケースではより正確であることにも注意してください[[ $(uname -s) =~ ^CYGWIN* ]]
Andreas Spindler 2014

上記はmacOSでexpr substr $(uname -s) 1 6エラー(expr: syntax error)が発生するため、より適切に機能します。
doekman '20

2

はい、こちらが私のやり方です。

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
}

私はこれを私のドットファイルで使用します


2

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

あなたが必要とするすべての情報。グーグルはあなたの友達です。

uname -sシステム名を照会するために使用します。

  • マック: Darwin
  • Cygwin: CYGWIN_...
  • Linux:さまざまな、LINUXほとんどの

2

この質問が尋ねられたとき、Linux用のWindowsサブシステムは存在しませんでした。それは私のテストでこれらの結果を与えました:

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

つまり、ネイティブLinuxと区別するためにuname -rが必要です。


1
残念ながら、Mingw-w64はまったく同じです。

1

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

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

そう、

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

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


-3

ジャスティンのおかげで、コマンドラインからこれだけを使用すると非常にうまくいきます:

#!/bin/bash

################################################## #########
# Bash script to find which OS
################################################## #########

OS=`uname`
echo "$OS"

ソース


スクリプトの新機能は何ですか?
マラウディン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.