Comment vérifier si vous utilisez Cygwin, Mac ou Linux?

j'ai un script shell qui est utilisé à la fois sur Windows/Cygwin et Mac et Linux. Il a besoin de variables légèrement différentes pour chaque version.

comment un script shell/bash peut-il détecter S'il tourne sous Cygwin, Mac ou Linux?

233
demandé sur bastibe 2010-08-12 13:10:22

10 réponses

habituellement, uname avec ses différentes options vous dira Dans quel environnement vous êtes en cours d'exécution:

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

et, selon le très utile schot (dans les commentaires), uname -s donne Darwin pour OSX et Linux Pour Linux, tandis que mon Cygwin donne CYGWIN_NT-5.1 . Mais vous pourriez avoir à expérimenter avec toutes sortes de versions différentes.

donc le code bash pour faire un tel contrôle serait le long de la lignes de:

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

notez que je suppose ici que vous exécutez réellement dans CygWin (l'interpréteur de commandes bash ) donc les chemins devraient déjà être correctement configurés. Comme le note un commentateur, vous pouvez exécuter le programme bash , en passant le script, à partir de cmd lui-même et cela peut avoir pour résultat que les chemins ne soient pas configurés comme nécessaire.

si vous êtes en faisant cela, il est de votre responsabilité de vous assurer que les exécutables corrects (c.-à-d. les exécutables CygWin) sont appelés, éventuellement en modifiant le chemin à l'avance ou en spécifiant complètement les emplacements exécutables (par exemple, /c/cygwin/bin/uname ).

187
répondu paxdiablo 2017-11-21 01:26:53

voici le script bash que j'ai utilisé pour détecter trois types D'OS différents (GNU/Linux, Mac OS X, Windows NT)

faites attention

  • dans votre script bash, utilisez #!/usr/bin/env bash au lieu de #!/bin/sh pour prévenir le problème causé par /bin/sh lié à un shell par défaut différent dans différentes plateformes, ou il y aura une erreur comme opérateur inattendu , c'est ce qui est arrivé sur mon ordinateur (Ubuntu 64 bits 12.04).
  • Mac OS X 10.6.8 (Snow Leopard) n'ont pas expr programme à moins que vous l'installez, donc je viens d'utiliser uname .

Design

  1. utilisez uname pour obtenir les informations du système (paramètre -s ).
  2. utilisez expr et substr pour traiter la chaîne.
  3. utiliser if elif fi pour faire le correspondant de l'emploi.
  4. vous pouvez ajouter plus de support système Si vous voulez, il suffit de suivre la spécification uname -s .

mise en Œuvre

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

test

  • Linux (Ubuntu 12.04 LTS, Kernel 3.2.0) testé OK.
  • OS X (10.6.8 Snow Leopard) testé OK.
  • Windows (Windows 7 64 bit) testé OK.

ce que j'ai appris

  1. vérifier les guillemets d'ouverture et de fermeture.
  2. vérifier s'il manque des parenthèses et des accolades {}

Références

266
répondu Albert 2017-05-23 11:54:59

Use uname -s ( --kernel-name ) parce que uname -o ( --operating-system ) n'est pas supporté sur certains systèmes D'exploitation comme Mac OS , Solaris . Vous pouvez également utiliser juste uname sans argument comme l'argument par défaut est -s ( --kernel-name ).

l'extrait ci-dessous ne nécessite pas (c'est à dire ne pas besoin de #!/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

ci-dessous Makefile est inspiré de projet 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
...

Voir aussi cette réponse complète à propos de uname -s et Makefile .

le tableau de correspondance en bas de cette réponse est de article de Wikipedia sur uname . Merci de contribuer à le tenir à jour (éditer la réponse ou poster un commentaire). Vous pouvez également mettre à jour L'article de Wikipedia et poster un commentaire pour me prévenir de votre contribution; -)

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

81
répondu olibre 2018-10-01 07:05:30

Bash définit la variable shell OSTYPE. À partir de man bash :

défini automatiquement à une chaîne qui décrit le système d'exploitation sur qui bash est en cours d'exécution.

cela a un petit avantage sur uname en ce qu'il ne nécessite pas de lancer un nouveau processus, donc sera plus rapide à exécuter.

Cependant, je suis incapable de trouver une liste officielle de prévu valeur. Pour moi sur Ubuntu 14.04, il est "linux-gnu'. J'ai gratté le web pour d'autres valeurs. D'où:

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

les astérisques sont importants dans certains cas - par exemple OSX ajoute un numéro de version D'OS après le 'darwin'. La valeur' win 'est en fait' win32', on m'a dit - peut-être qu'il y a un'win64'?

peut-être pourrions-nous travailler ensemble pour remplir une table de valeurs vérifiées ici:

  • Linux Ubuntu (incl. WSL ): linux-gnu
  • Cygwin 64 bits: cygwin
  • Msys / MINGW (Git Bash for Windows): msys

(veuillez ajouter votre valeur si elle diffère des entrées existantes)

43
répondu Jonathan Hartley 2018-03-23 17:47:48

pour construire sur la réponse D'Albert, j'aime utiliser $COMSPEC pour la détection des fenêtres:

#!/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 "151900920": this script does not support Windows \:\(
fi

cela évite l'analyse des variantes des noms de fenêtres pour $OS , et l'analyse des variantes de uname comme MINGW, Cygwin, etc.

Background: %COMSPEC% est une variable D'environnement Windows spécifiant le chemin complet vers le processeur de commande (alias le shell Windows). La valeur de cette variable est typiquement %SystemRoot%\system32\cmd.exe , qui s'évalue généralement à C:\Windows\system32\cmd.exe .

9
répondu Steve Jansen 2013-09-13 16:14:32
# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
    echo Cygwin rulez
else 
    echo Unix is king
fi

si les 6 premiers caractères de la commande uname-s sont "CYGWIN", un système cygwin est supposé

8
répondu Jan Helge 2018-09-20 09:34:45

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

toutes les infos dont vous aurez besoin. Google est votre ami.

utilisez uname -s pour interroger le nom du système.

  • Mac: Darwin
  • Cygwin: CYGWIN_...
  • Linux: divers, LINUX pour la plupart
4
répondu rubenvb 2015-07-21 08:21:14

Ok, voici ma façon.

osis()
{
    local n=0
    if [[ "" = "-n" ]]; then n=1;shift; fi

    # echo $OS|grep  -i >/dev/null
    uname -s |grep -i "" >/dev/null

    return $(( $n ^ $? ))
}

p.ex.

osis Darwin &&
{
    log_debug Detect mac osx
}
osis Linux &&
{
    log_debug Detect linux
}
osis -n Cygwin &&
{
    log_debug Not Cygwin
}

Je l'utilise dans mon dotfiles

1
répondu wener 2015-02-13 06:46:43

Utiliser la ligne de commande fonctionne très fine, merci à Justin:

#!/bin/bash

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

OS=`uname`
echo "$OS"

source

0
répondu lizardhr 2014-07-25 21:17:41

je suppose que la réponse uname est imbattable, surtout en termes de propreté.

bien que cela prenne un temps ridicule à exécuter, j'ai trouvé que tester la présence de fichiers spécifiques me donne aussi de bons résultats et plus rapides, puisque je n'invoque pas un exécutable:

,

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

utilise juste une vérification rapide de la présence du fichier Bash. Comme je suis sur Windows en ce moment, je ne peux pas vous dire de fichiers spécifiques pour Linuxes et Mac OS X de ma tête, mais je suis presque sûr qu'ils existent. :- )

0
répondu Charles Roberto Canato 2015-08-12 00:12:49