Eu tenho um script de shell que é usado no Windows / Cygwin e Mac e Linux. Ele precisa de variáveis ligeiramente diferentes para cada versão.
Como um script shell / bash detecta se está sendo executado no Cygwin, em um Mac ou no Linux?
fonte
Eu tenho um script de shell que é usado no Windows / Cygwin e Mac e Linux. Ele precisa de variáveis ligeiramente diferentes para cada versão.
Como um script shell / bash detecta se está sendo executado no Cygwin, em um Mac ou no Linux?
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
paraC:
.How can a shell/bash script detect ...
e a outra.uname -s
acaba chamando o queuname
for o primeiro no seu caminho atual, que no meu sistema é a versão instalada com ageda
qual retorna o textoWindowsNT
. 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.Aqui está o script bash que usei para detectar três tipos diferentes de SO (GNU / Linux, Mac OS X, Windows NT)
Preste atenção
#!/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 usouname
.Projeto
uname
para obter as informações do sistema (-s
parâmetro).expr
esubstr
para lidar com a string.if
elif
fi
para fazer o trabalho correspondente.uname -s
especificações.Implementação
Teste
O que eu aprendi
Referências
fonte
[ "$(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: Seuname -s
começa com CYGWIN então ...if [[ $(uname -s) == CYGWIN* ]]; then
uname -s
trará algo diferente de "Linux"?Use
uname -s
(--kernel-name
) porqueuname -o
(--operating-system
) não é suportado em alguns sistemas operacionais, como Mac OS e Solaris . Você também pode usar apenasuname
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
)O abaixo
Makefile
é inspirado no projeto Git (config.mak.uname
) .Veja também esta resposta completa sobre
uname -s
eMakefile
.A tabela de correspondência na parte inferior desta resposta é do artigo
uname
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
fonte
~/.profile
(para definir variáveis de ambiente como$PATH
- comentar para fornecer palavras-chave de pesquisa para posteridade).uname -sr
e compararLinux*Microsoft)
antesLinux*)
.Bash define a variável do shell OSTYPE. De
man bash
: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:
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)
fonte
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 daOS
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:Isso evita analisar variantes de nomes do Windows
$OS
e analisar variantes deuname
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 comoC:\Windows\system32\cmd.exe
.fonte
Se os 6 primeiros caracteres do comando uname -s forem "CYGWIN", será assumido um sistema cygwin
fonte
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.
por exemplo
Eu uso isso nos meus dotfiles
fonte
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 maioriafonte
O Subsistema Windows para Linux não existia quando essa pergunta foi feita. Deu estes resultados no meu teste:
Isso significa que você precisa de uname -r para diferenciá-lo do Linux nativo.
fonte
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. :-)
fonte
Use apenas isso na linha de comando, funciona muito bem, graças a Justin:
fonte
fonte