Respostas:
Geralmente, unamecom 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 -sdá Darwinpara OSX e LinuxLinux, enquanto meu Cygwin dá CYGWIN_NT-5.1. Mas você pode ter que experimentar todos os tipos de versões diferentes.
Portanto, o bashcó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 bashshell dele) para caminhos já deve estar configurado corretamente. Como observa um comentarista, você pode executar o bashprograma, transmitindo o script por cmdsi 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á /cygdriveprefixo, apenas /cpara C:.
How can a shell/bash script detect ...e a outra.
uname -sacaba chamando o que unamefor o primeiro no seu caminho atual, que no meu sistema é a versão instalada com a gedaqual 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 bashvez de #!/bin/shevitar o problema causado por /bin/shvinculado 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).exprprograma, a menos que você o instale, então eu apenas o uso uname.unamepara obter as informações do sistema ( -sparâmetro).expre substrpara lidar com a string.if elif fipara fazer o trabalho correspondente.uname -sespecificaçõ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 -scomeça com CYGWIN então ...
if [[ $(uname -s) == CYGWIN* ]]; then
uname -strará 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 unamesem 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 -seMakefile .
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 -sre 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-gnucygwinmsys(Anexe seu valor se ele diferir das entradas existentes)
env | grep OSTYPE, mas você vai vê-lo sobset | grep OSTYPE
OSTYPEvariável do Bash (conftypes.h) é configurada no tempo de construção usando a cópia exata da OSvariá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 $COMSPECpara 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 $OSe analisar variantes de unamecomo 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* ]; thenparece 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 6gera 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 -spara consultar o nome do sistema.
DarwinCYGWIN_...LINUXpara 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"