Respostas:
Geralmente, uname
com suas várias opções, você informa em que ambiente está executando:
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, de acordo com o muito útil schot
(nos comentários), uname -s
dá Darwin
para OSX e Linux
Linux, enquanto meu Cygwin dá CYGWIN_NT-5.1
. Mas você pode ter que experimentar todos os tipos de versões diferentes.
Portanto, o bash
código para fazer essa verificação seria ao longo das linhas 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}
Note que eu estou assumindo aqui que você está realmente correndo dentro CygWin (o bash
shell dele) para caminhos já deve estar configurado corretamente. Como observa um comentarista, você pode executar o bash
programa, transmitindo o script por cmd
si mesmo e isso pode resultar na não configuração dos caminhos conforme necessário.
Se você estiver fazendo isso, é sua responsabilidade garantir que os executáveis corretos (ou seja, os CygWin) sejam chamados, possivelmente modificando o caminho antecipadamente ou especificando completamente os locais dos executáveis (por exemplo, /c/cygwin/bin/uname
).
MINGW32_NT-6.1
. Além disso, não há /cygdrive
prefixo, apenas /c
para C:
.
How can a shell/bash script detect ...
e a outra.
uname -s
acaba chamando o que uname
for o primeiro no seu caminho atual, que no meu sistema é a versão instalada com a geda
qual retorna o texto WindowsNT
. Poderia igualmente ser a versão MinGW, conforme descrito acima. Uma detecção confiável para o cygwin não deve depender do caminho que está sendo definido adequadamente, IMO. Portanto, $(uname -s)
deve ser alterado $(/bin/uname -s)
para detectar cygwin.
#!/usr/bin/env bash
vez de #!/bin/sh
evitar o problema causado por /bin/sh
vinculado a diferentes shell padrão em plataformas diferentes, ou haverá um erro como operador inesperado , foi o que aconteceu no meu computador (Ubuntu 64 bits 12.04).expr
programa, a menos que você o instale, então eu apenas o uso uname
.uname
para obter as informações do sistema ( -s
parâmetro).expr
e substr
para lidar com a string.if
elif
fi
para fazer o trabalho correspondente.uname -s
especificações.#!/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)"
é um pouco estranha. Há mais bonitas maneiras de fazer isso, por exemplo: if [ `uname -s` == CYGWIN* ]; then
. Leia: Se uname -s
começa com CYGWIN então ...
if [[ $(uname -s) == CYGWIN* ]]; then
uname -s
trará algo diferente de "Linux"?
Use uname -s
( --kernel-name
) porque uname -o
( --operating-system
) não é suportado em alguns sistemas operacionais, como Mac OS e Solaris . Você também pode usar apenas uname
sem nenhum argumento, já que o argumento padrão é -s
( --kernel-name
).
O snippet abaixo não requer festança(ou seja, não requer #!/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
O abaixo Makefile
é inspirado no projeto 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
...
Veja também esta resposta completa sobre uname -s
eMakefile
.
A tabela de correspondência na parte inferior desta resposta é do artigouname
da Wikipedia sobre . Contribua para mantê-lo atualizado (edite a resposta ou publique um comentário). Você também pode atualizar o artigo da Wikipedia e postar um comentário para me notificar sobre sua contribuição ;-)
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
(para definir variáveis de ambiente como $PATH
- comentar para fornecer palavras-chave de pesquisa para posteridade).
uname -sr
e comparar Linux*Microsoft)
antes Linux*)
.
Bash define a variável do shell OSTYPE. De man bash
:
Configure automaticamente como uma sequência que descreva o sistema operacional no qual o bash está sendo executado.
Isso tem uma pequena vantagem uname
, pois não requer o lançamento de um novo processo, portanto, será mais rápido para executar.
No entanto, não consigo encontrar uma lista autorizada de valores esperados. Para mim, no Ubuntu 14.04, está definido como 'linux-gnu'. Raspei a web em busca de outros valores. Conseqüentemente:
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
Os asteriscos são importantes em alguns casos - por exemplo, o OSX anexa um número de versão do SO após o 'darwin'. O valor 'win' é realmente 'win32', disseram-me - talvez exista um 'win64'?
Talvez possamos trabalhar juntos para preencher uma tabela de valores verificados aqui:
linux-gnu
cygwin
msys
(Anexe seu valor se ele diferir das entradas existentes)
env | grep OSTYPE
, mas você vai vê-lo sobset | grep OSTYPE
OSTYPE
variável do Bash (conftypes.h) é configurada no tempo de construção usando a cópia exata da OS
variável do automake (Makefile.in) . Pode-se consultar o arquivo lib / config.sub da automake para todos os tipos disponíveis.
Para aproveitar a resposta de Albert, eu gosto de usar $COMSPEC
para detectar o 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
Isso evita analisar variantes de nomes do Windows $OS
e analisar variantes de uname
como MINGW, Cygwin etc.
Background: %COMSPEC%
é uma variável de ambiente do Windows que especifica o caminho completo para o processador de comandos (também conhecido como shell do Windows). O valor dessa variável é tipicamente %SystemRoot%\system32\cmd.exe
, que normalmente é avaliado como 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 os 6 primeiros caracteres do comando uname -s forem "CYGWIN", será assumido um sistema cygwin
if [ `uname -s` == CYGWIN* ]; then
parece melhor e funciona da mesma maneira.
[[ $(uname -s) == CYGWIN* ]]
. Note-se também que as expressões regulares estendidas são mais precisos no nosso caso: [[ $(uname -s) =~ ^CYGWIN* ]]
.
expr substr $(uname -s) 1 6
gera um erro ( expr: syntax error
) no macOS.
Ok, aqui está o meu caminho.
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 ^ $? ))
}
por exemplo
osis Darwin &&
{
log_debug Detect mac osx
}
osis Linux &&
{
log_debug Detect linux
}
osis -n Cygwin &&
{
log_debug Not Cygwin
}
Eu uso isso nos meus dotfiles
http://en.wikipedia.org/wiki/Uname
Toda a informação que você precisa. Google é seu amigo.
Use uname -s
para consultar o nome do sistema.
Darwin
CYGWIN_...
LINUX
para a maioriaO Subsistema Windows para Linux não existia quando essa pergunta foi feita. Deu estes resultados no meu teste:
uname -s -> Linux
uname -o -> GNU/Linux
uname -r -> 4.4.0-17763-Microsoft
Isso significa que você precisa de uname -r para diferenciá-lo do Linux nativo.
Eu acho que a resposta uname é imbatível, principalmente em termos de limpeza.
Embora demore um tempo ridículo para executar, descobri que o teste para a presença de arquivos específicos também me fornece resultados bons e mais rápidos, pois não estou invocando um executável:
Assim,
[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running
apenas usa uma verificação rápida de presença de arquivo Bash. Como estou no Windows no momento, não posso informar nenhum arquivo específico para Linux e Mac OS X, mas tenho certeza de que eles existem. :-)
Use apenas isso na linha de comando, funciona muito bem, graças a Justin:
#!/bin/bash
################################################## #########
# Bash script to find which OS
################################################## #########
OS=`uname`
echo "$OS"