Risposte:
Di solito, uname
con le sue varie opzioni, ti dirà in quale ambiente stai eseguendo:
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
E, secondo l'utilissimo schot
(nei commenti), uname -s
dà Darwin
per OSX e Linux
per Linux, mentre il mio Cygwin dà CYGWIN_NT-5.1
. Ma potresti dover sperimentare tutti i tipi di versioni diverse.
Quindi il bash
codice per fare un tale controllo sarebbe sulla falsariga di:
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
echo ${machine}
Si noti che sto dando per scontato che si sta effettivamente in esecuzione all'interno CygWin (la bash
shell di esso) in modo da percorsi dovrebbero già essere impostati correttamente. Come osserva un commentatore, è possibile eseguire il bash
programma, passando lo script, da cmd
solo e ciò può comportare che i percorsi non vengano impostati come necessario.
Se lo stai facendo, è tua responsabilità assicurarti che vengano richiamati gli eseguibili corretti (cioè quelli CygWin), possibilmente modificando in anticipo il percorso o specificando completamente le posizioni degli eseguibili (ad es /c/cygwin/bin/uname
.).
MINGW32_NT-6.1
. Inoltre, non esiste un /cygdrive
prefisso, solo /c
per C:
.
How can a shell/bash script detect ...
e l'altra no .
uname -s
finisce per chiamare qualunque cosa uname
sia la prima nel tuo percorso corrente, che sul mio sistema risulta essere la versione installata con la geda
quale restituisce il testo WindowsNT
. Potrebbe ugualmente essere la versione di MinGW come descritto sopra, però. Un rilevamento affidabile per Cygwin non deve basarsi sul percorso impostato in modo appropriato, IMO. Pertanto, $(uname -s)
dovrebbe essere modificato $(/bin/uname -s)
per rilevare Cygwin.
#!/usr/bin/env bash
invece di #!/bin/sh
per evitare il problema causato dal /bin/sh
collegamento a diverse shell predefinite in piattaforme diverse, o ci saranno errori come operatori imprevisti , ecco cosa è successo sul mio computer (Ubuntu 64 bit 12.04).expr
programma se non lo installi, quindi lo uso e basta uname
.uname
per ottenere le informazioni di sistema (-s
parametro).expr
esubstr
gestire la stringa.if
elif
fi
per eseguire il lavoro corrispondente.uname -s
specifiche.#!/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
[ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]
.
"$(expr substr $(uname -s) 1 5)"
è un po 'strana. Ci sono più belle modi per farlo, per esempio: if [ `uname -s` == CYGWIN* ]; then
. Leggi: se uname -s
inizia con CYGWIN, allora ...
if [[ $(uname -s) == CYGWIN* ]]; then
uname -s
produrrà qualcosa di diverso da "Linux"?
Usa uname -s
( --kernel-name
) perché uname -o
( --operating-system
) non è supportato su alcuni sistemi operativi come Mac OS e Solaris . Puoi anche usare solo uname
senza alcun argomento poiché l'argomento predefinito è -s
( --kernel-name
).
Lo snippet di seguito non richiede bash(cioè non richiede #!/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
Il seguito Makefile
è ispirato al progetto 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
...
Vedi anche questa risposta completa su uname -s
eMakefile
.
La tabella delle corrispondenze in fondo a questa risposta è tratta dall'articolo di Wikipedia suuname
. Contribuisci a mantenerlo aggiornato (modifica la risposta o pubblica un commento). Puoi anche aggiornare l'articolo di Wikipedia e pubblicare un commento per avvisarmi del tuo contributo ;-)
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
~/.profile
(per impostare variabili d'ambiente come $PATH
- commentare per fornire parole chiave di ricerca per i posteri).
uname -sr
e confrontare Linux*Microsoft)
prima Linux*)
.
Bash imposta la variabile shell OSTYPE. Da man bash
:
Impostato automaticamente su una stringa che descrive il sistema operativo su cui è in esecuzione bash.
Questo ha un piccolo vantaggio uname
in quanto non richiede l'avvio di un nuovo processo, quindi sarà più veloce da eseguire.
Tuttavia, non riesco a trovare un elenco autorevole di valori previsti. Per me su Ubuntu 14.04 è impostato su "linux-gnu". Ho raschiato il web per altri valori. Quindi:
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
Gli asterischi sono importanti in alcuni casi, ad esempio OSX aggiunge un numero di versione del sistema operativo dopo "darwin". Il valore 'win' è in realtà 'win32', mi viene detto - forse c'è un 'win64'?
Forse potremmo lavorare insieme per popolare una tabella di valori verificati qui:
linux-gnu
cygwin
msys
(Aggiungi il tuo valore se differisce dalle voci esistenti)
env | grep OSTYPE
, ma lo vedrai sottoset | grep OSTYPE
OSTYPE
variabile di Bash (conftypes.h) è configurata al momento della compilazione usando la copia esatta della OS
variabile di automake (Makefile.in) . Si può consultare il file lib / config.sub di automake per tutti i tipi disponibili.
Per basarmi sulla risposta di Albert, mi piace usare $COMSPEC
per rilevare Windows:
#!/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
Questo evita l'analisi delle varianti dei nomi di Windows $OS
e l'analisi delle varianti uname
come MINGW, Cygwin, ecc.
Sfondo: %COMSPEC%
è una variabile ambientale di Windows che specifica il percorso completo del processore dei comandi (noto anche come shell di Windows). Il valore di questa variabile è in genere %SystemRoot%\system32\cmd.exe
, che in genere viene valutato 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
Se i primi 6 caratteri del comando uname -s sono "CYGWIN", si assume un sistema cygwin
if [ `uname -s` == CYGWIN* ]; then
sembra migliore e funziona allo stesso modo.
[[ $(uname -s) == CYGWIN* ]]
. Si noti inoltre che estesi espressioni regolari sono più precisi nel nostro caso: [[ $(uname -s) =~ ^CYGWIN* ]]
.
expr substr $(uname -s) 1 6
dà un errore ( expr: syntax error
) su macOS.
Ok, ecco la mia strada.
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 ^ $? ))
}
per esempio
osis Darwin &&
{
log_debug Detect mac osx
}
osis Linux &&
{
log_debug Detect linux
}
osis -n Cygwin &&
{
log_debug Not Cygwin
}
Lo uso nei miei dotfile
http://en.wikipedia.org/wiki/Uname
Tutte le informazioni di cui avrai mai bisogno. Google è tuo amico.
Utilizzare uname -s
per interrogare il nome del sistema.
Darwin
CYGWIN_...
LINUX
per la maggior parteIl sottosistema Windows per Linux non esisteva quando veniva posta questa domanda. Ha dato questi risultati nel mio test:
uname -s -> Linux
uname -o -> GNU/Linux
uname -r -> 4.4.0-17763-Microsoft
Ciò significa che è necessario uname -r per distinguerlo da Linux nativo.
Immagino che la risposta sbagliata sia imbattibile, soprattutto in termini di pulizia.
Anche se ci vuole un tempo ridicolo per eseguire, ho scoperto che il test per la presenza di file specifici mi dà anche risultati buoni e più rapidi, dal momento che non sto invocando un eseguibile:
Così,
[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running
utilizza solo un rapido controllo di presenza del file Bash. Dato che sono su Windows in questo momento, non posso dirti alcun file specifico per Linux e Mac OS X dalla mia testa, ma sono abbastanza sicuro che esistano. :-)
Utilizzare solo questo dalla riga di comando funziona molto bene, grazie a Justin:
#!/bin/bash
################################################## #########
# Bash script to find which OS
################################################## #########
OS=`uname`
echo "$OS"