469 Stimmen

Wie kann man überprüfen, ob das Programm unter Cygwin, Mac oder Linux läuft?

Ich habe ein Shell-Skript, das sowohl unter Windows/Cygwin als auch unter Mac und Linux verwendet wird. Es benötigt leicht unterschiedliche Variablen für jede Version.

Wie kann ein Shell/Bash-Skript erkennen, ob es in Cygwin, auf einem Mac oder unter Linux läuft?

476voto

paxdiablo Punkte 809679

Normalerweise, uname mit seinen verschiedenen Optionen sagt Ihnen, in welcher Umgebung Sie arbeiten:

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

Und laut dem sehr hilfreichen schot (in den Kommentaren), uname -s gibt Darwin für OSX und Linux für Linux, während mein Cygwin eine CYGWIN_NT-5.1 . Aber vielleicht müssen Sie mit allen möglichen Versionen experimentieren.

Also die bash Der Code für eine solche Prüfung würde in etwa so aussehen:

unameOut="$(uname -s)"
case "${unameOut}" in
    Linux*)     machine=Linux;;
    Darwin*)    machine=Mac;;
    CYGWIN*)    machine=Cygwin;;
    MINGW*)     machine=MinGw;;
    *)          machine="UNKNOWN:${unameOut}"
esac
echo ${machine}

Beachten Sie, dass ich hier davon ausgehe, dass Sie tatsächlich das Programm innerhalb CygWin (das bash Shell), so dass die Pfade bereits korrekt eingerichtet sein sollten. Wie ein Kommentator anmerkt, können Sie die bash Programm, das das Skript übergibt, von cmd selbst, was dazu führen kann, dass die Pfade nicht wie erforderlich eingerichtet werden.

Wenn Sie son Dabei müssen Sie sicherstellen, dass die richtigen ausführbaren Dateien (d.h. die CygWin-Dateien) aufgerufen werden, indem Sie den Pfad vorher ändern oder die Speicherorte der ausführbaren Dateien vollständig angeben (z.B., /c/cygwin/bin/uname ).

398voto

Albert Punkte 9839

Erkennung von drei verschiedenen Betriebssystemen (GNU/Linux, Mac OS X, Windows NT)

Anmerkungen

  • Verwenden Sie in Ihrem Bash-Skript #!/usr/bin/env bash anstelle von #!/bin/sh um das Problem zu verhindern, das durch /bin/sh mit verschiedenen Standard-Shells auf verschiedenen Plattformen verknüpft, oder es wird ein Fehler wie unerwarteter Betreiber Das ist, was auf meinem Computer (Ubuntu 64 bits 12.04) passiert ist.
  • Mac OS X 10.6.8 (Snow Leopard) haben keine expr Programm, es sei denn, man installiert es, also verwende ich einfach uname .

Gestaltung

  1. Utilice uname um die Systeminformationen zu erhalten ( -s Parameter).
  2. Utilice expr y substr um mit der Zeichenfolge umzugehen.
  3. Utilice if elif fi um die entsprechende Aufgabe zu erfüllen.
  4. Sie können weitere Systemunterstützung hinzufügen, wenn Sie wollen, folgen Sie einfach der uname -s Spezifikation.

Umsetzung

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

Prüfung

  • Linux (Ubuntu 12.04 LTS, Kernel 3.2.0) getestet OK.
  • OS X (10.6.8 Snow Leopard) wurde problemlos getestet.
  • Windows (Windows 7 64 Bit) wurde problemlos getestet.

Was ich gelernt habe

  1. Achten Sie auf öffnende und schließende Anführungszeichen.
  2. Suche nach fehlenden Klammern und geschweiften Klammern {}

Referenzen

195voto

oHo Punkte 45335

Utilice uname -s ( --kernel-name ) denn uname -o ( --operating-system ) wird von einigen Betriebssystemen nicht unterstützt, wie z.B. Mac OS y Solaris . Sie können auch nur uname ohne jedes Argument da das Standardargument -s ( --kernel-name ).

Das folgende Snippet erfordert keine bash (d.h. erfordert nicht #!/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

Die folgenden Makefile ist inspiriert von Git-Projekt ( 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
...

Siehe auch diese vollständige Antwort über uname -s y Makefile .

Die Korrespondenztabelle unten in dieser Antwort stammt aus Wikipedia-Artikel über uname . Bitte tragen Sie dazu bei, sie auf dem neuesten Stand zu halten (bearbeiten Sie die Antwort oder schreiben Sie einen Kommentar). Sie können auch den Wikipedia-Artikel aktualisieren und einen Kommentar hinterlassen, um mich über Ihren Beitrag zu informieren ;-)

<strong><code>Operating System </code></strong> <strong><code>uname -s</code></strong>
<code>Mac OS X </code> <code>Darwin</code>
<code>Cygwin 32-bit (Win-XP) </code> <code>CYGWIN_NT-5.1</code>
<code>Cygwin 32-bit (Win-7 32-bit)</code><code>CYGWIN_NT-6.1</code>
<code>Cygwin 32-bit (Win-7 64-bit)</code><code>CYGWIN_NT-6.1-WOW64</code>
<code>Cygwin 64-bit (Win-7 64-bit)</code><code>CYGWIN_NT-6.1</code>
<code>MinGW (Windows 7 32-bit) </code> <code>MINGW32_NT-6.1</code>
<code>MinGW (Windows 10 64-bit) </code> <code>MINGW64_NT-10.0</code>
<code>Interix (Services for UNIX) </code> <code>Interix</code>
<code>MSYS </code> <code>MSYS_NT-6.1</code>
<code>MSYS2 </code> <code>MSYS_NT-10.0-17763</code>
<code><a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux" rel="noreferrer">Windows Subsystem for Linux</a> </code> <code>Linux</code>
<code>Android </code> <code>Linux</code>
<code>coreutils </code> <code>Linux</code>
<code>CentOS </code> <code>Linux</code>
<code>Fedora </code> <code>Linux</code>
<code>Gentoo </code> <code>Linux</code>
<code>Red Hat Linux </code> <code>Linux</code>
<code>Linux Mint </code> <code>Linux</code>
<code>openSUSE </code> <code>Linux</code>
<code>Ubuntu </code> <code>Linux</code>
<code>Unity Linux </code> <code>Linux</code>
<code>Manjaro Linux </code> <code>Linux</code>
<code>OpenWRT r40420 </code> <code>Linux</code>
<code>Debian (Linux) </code> <code>Linux</code>
<code>Debian (GNU Hurd) </code> <code>GNU</code>
<code>Debian (kFreeBSD) </code> <code>GNU/kFreeBSD</code>
<code>FreeBSD </code> <code>FreeBSD</code>
<code>NetBSD </code> <code>NetBSD</code>
<code>OpenBSD </code> <code>OpenBSD</code>
<code>DragonFlyBSD </code> <code>DragonFly</code>
<code>Haiku </code> <code>Haiku</code>
<code>NonStop </code> <code>NONSTOP_KERNEL</code>
<code>QNX </code> <code>QNX</code>
<code>ReliantUNIX </code> <code>ReliantUNIX-Y</code>
<code>SINIX </code> <code>SINIX-Y</code>
<code>Tru64 </code> <code>OSF1</code>
<code>Ultrix </code> <code>ULTRIX</code>
<code>IRIX 32 bits </code> <code>IRIX</code>
<code>IRIX 64 bits </code> <code>IRIX64</code>
<code>MINIX </code> <code>Minix</code>
<code>Solaris </code> <code>SunOS</code>
<code>UWIN (64-bit Windows 7) </code> <code>UWIN-W7</code>
<code>SYS$UNIX:SH on OpenVMS </code> <code>IS/WB</code>
<code>z/OS USS </code> <code>OS/390</code>
<code>Cray </code> <code>sn5176</code>
<code>(SCO) OpenServer </code> <code>SCO_SV</code>
<code>(SCO) System V </code> <code>SCO_SV</code>
<code>(SCO) UnixWare </code> <code>UnixWare</code>
<code>IBM AIX </code> <code>AIX</code>
<code>IBM i with QSH </code> <code>OS400</code>
<code>HP-UX </code> <code>HP-UX</code>

90voto

Jonathan Hartley Punkte 14645

Die Bash setzt die Shell-Variable OSTYPE. Von man bash :

Automatisch auf eine Zeichenkette gesetzt, die das Betriebssystem auf beschreibt, auf dem die Bash ausgeführt wird.

Dies hat einen kleinen Vorteil gegenüber uname da es nicht erforderlich ist, einen neuen Prozess zu starten, so dass die Ausführung schneller geht.

Ich kann jedoch keine verbindliche Liste der erwarteten Werte finden. Bei mir auf Ubuntu 14.04 ist er auf "linux-gnu" eingestellt. Ich habe das Web nach anderen Werten durchforstet. Daher:

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

Die Sternchen sind in einigen Fällen wichtig - zum Beispiel hängt OSX eine OS-Versionsnummer nach dem 'darwin' an. Der "win"-Wert ist eigentlich "win32", wie mir gesagt wurde - vielleicht gibt es auch ein "win64"?

Vielleicht können wir hier gemeinsam eine Tabelle mit geprüften Werten aufstellen:

  • Linux Ubuntu (einschließlich. WSL ): linux-gnu
  • Cygwin 64-Bit: cygwin
  • Msys/MINGW (Git Bash für Windows): msys

(Bitte fügen Sie Ihren Wert hinzu, wenn er von den vorhandenen Einträgen abweicht)

13voto

Jan Helge Punkte 141
# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
    echo Cygwin rulez
else 
    echo Unix is king
fi

Wenn die ersten 6 Zeichen des Befehls uname -s "CYGWIN" sind, wird ein Cygwin-System angenommen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X