Mam skrypt powłoki używany zarówno w systemach Windows / Cygwin, Mac, jak i Linux. Potrzebuje nieco innych zmiennych dla każdej wersji.
W jaki sposób skrypt powłoki / bash może wykryć, czy działa w Cygwin, na Macu czy w Linuksie?
źródło
Mam skrypt powłoki używany zarówno w systemach Windows / Cygwin, Mac, jak i Linux. Potrzebuje nieco innych zmiennych dla każdej wersji.
W jaki sposób skrypt powłoki / bash może wykryć, czy działa w Cygwin, na Macu czy w Linuksie?
Zazwyczaj uname
dzięki różnym opcjom powiesz w jakim środowisku pracujesz:
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
I, zgodnie z bardzo pomocnymi schot
(w komentarzach), uname -s
daje Darwin
dla OSX i Linux
dla Linuksa, podczas gdy mój Cygwin daje CYGWIN_NT-5.1
. Ale być może będziesz musiał poeksperymentować z różnego rodzaju wersjami.
Tak więc bash
kod do wykonania takiej kontroli byłby następujący:
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
echo ${machine}
Zauważ, że zakładam tutaj, że faktycznie działasz w CygWin (jego bash
powłoce), więc ścieżki powinny być już poprawnie ustawione. Jak zauważa jeden z komentatorów, możesz uruchomić bash
program, przekazując skrypt od cmd
siebie, co może spowodować, że ścieżki nie zostaną skonfigurowane w razie potrzeby.
Jeśli to robisz, Twoim obowiązkiem jest upewnić się, że wywoływane są poprawne pliki wykonywalne (tj. CygWin), być może poprzez uprzednią modyfikację ścieżki lub pełne określenie plików wykonywalnych (np /c/cygwin/bin/uname
.).
MINGW32_NT-6.1
. Ponadto nie ma/cygdrive
przedrostka, tylko/c
dlaC:
.How can a shell/bash script detect ...
a druga tak.uname -s
kończy się wywoływaniem tego, couname
pierwsze na twojej bieżącej ścieżce, które w moim systemie okazuje się być zainstalowaną wersją,geda
która zwraca tekstWindowsNT
. Może to być jednak wersja MinGW, jak opisano powyżej. Wiarygodne wykrywanie cygwina nie może polegać na odpowiednio ustawionej ścieżce, IMO. Dlatego$(uname -s)
powinien zostać zmieniony$(/bin/uname -s)
na wykrywanie cygwina.Oto skrypt bash, którego użyłem do wykrycia trzech różnych typów systemów operacyjnych (GNU / Linux, Mac OS X, Windows NT)
Zwróć uwagę
#!/usr/bin/env bash
zamiast,#!/bin/sh
aby zapobiec problemowi związanemu z/bin/sh
połączeniem z inną domyślną powłoką na różnych platformach, w przeciwnym razie wystąpi błąd, taki jak nieoczekiwany operator , tak się stało na moim komputerze (Ubuntu 64 bity 12.04).expr
programu, chyba że go zainstalujesz, więc po prostu go używamuname
.Projekt
uname
do uzyskania informacji o systemie (-s
parametr).expr
i,substr
aby poradzić sobie z ciągiem.if
elif
fi
aby wykonać pasującą pracę.uname -s
specyfikacją.Realizacja
Testowanie
Czego się nauczyłem
Bibliografia
źródło
[ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]
."$(expr substr $(uname -s) 1 5)"
jest trochę dziwne. Są bardziej ładne sposobów aby to zrobić, na przykład:if [ `uname -s` == CYGWIN* ]; then
. Przeczytaj: jeśliuname -s
zaczyna się od CYGWIN, to ...if [[ $(uname -s) == CYGWIN* ]]; then
uname -s
można uzyskać coś innego niż „Linux”?Użyj
uname -s
(--kernel-name
), ponieważuname -o
(--operating-system
) nie jest obsługiwane w niektórych systemach operacyjnych, takich jak Mac OS i Solaris . Możesz także użyćuname
bez żadnego argumentu, ponieważ domyślnym argumentem jest-s
(--kernel-name
).Poniższy fragment kodu nie wymaga grzmotnąć(tj. nie wymaga
#!/bin/bash
)Poniżej
Makefile
inspirowane jest projektem Git (config.mak.uname
) .Zobacz także pełną odpowiedź na temat
uname -s
iMakefile
.Tabela korespondencji na dole tej odpowiedzi pochodzi z artykułu w Wikipedii na temat
uname
. Proszę przyczynić się do jego aktualności (edytuj odpowiedź lub opublikuj komentarz). Możesz również zaktualizować artykuł w Wikipedii i opublikować komentarz, aby powiadomić mnie o swoim wkładzie ;-)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
źródło
~/.profile
(aby ustawić zmienne środowiskowe, takie jak$PATH
- komentowanie w celu zapewnienia słów kluczowych dla potomności).uname -sr
i porównujęLinux*Microsoft)
wcześniejLinux*)
.Bash ustawia zmienną powłoki OSTYPE. Od
man bash
:Ma to niewielką przewagę nad
uname
tym, że nie wymaga uruchamiania nowego procesu, więc będzie można go szybciej wykonać.Nie mogę jednak znaleźć wiarygodnej listy oczekiwanych wartości. Dla mnie na Ubuntu 14.04 jest ustawiony na „linux-gnu”. Zeskrobałem sieć w poszukiwaniu innych wartości. W związku z tym:
Gwiazdki są ważne w niektórych przypadkach - na przykład OSX dołącza numer wersji systemu operacyjnego po „darwin”. Powiedziano mi, że wartość „win” to tak naprawdę „win32” - może istnieje „win64”?
Być może moglibyśmy pracować razem, aby wypełnić tabelę zweryfikowanych wartości tutaj:
linux-gnu
cygwin
msys
(Proszę dołączyć swoją wartość, jeśli różni się ona od istniejących pozycji)
źródło
env | grep OSTYPE
set | grep OSTYPE
OSTYPE
zmienna Basha (conftypes.h) jest konfigurowana w czasie kompilacji przy użyciu dokładnej kopiiOS
zmiennej automake (Makefile.in) . Można sprawdzić plik lib / config.sub automake dla wszystkich dostępnych typów.Opierając się na odpowiedzi Alberta, lubię używać
$COMSPEC
do wykrywania systemu Windows:Pozwala to uniknąć analizowania wariantów nazw systemu Windows
$OS
i analizowania wariantówuname
takich jak MINGW, Cygwin itp.Tło:
%COMSPEC%
to zmienna środowiskowa systemu Windows określająca pełną ścieżkę do procesora poleceń (zwanego również powłoką systemu Windows). Wartość tej zmiennej wynosi zazwyczaj%SystemRoot%\system32\cmd.exe
, co zwykle stanowi wartośćC:\Windows\system32\cmd.exe
.źródło
Jeśli 6 pierwszych znaków komendy uname -s to „CYGWIN”, zakłada się system cygwin
źródło
if [ `uname -s` == CYGWIN* ]; then
wygląda lepiej i działa tak samo.[[ $(uname -s) == CYGWIN* ]]
. Należy również zauważyć, że rozszerzone wyrażenia regularne są bardziej precyzyjne w naszym przypadku:[[ $(uname -s) =~ ^CYGWIN* ]]
.expr substr $(uname -s) 1 6
daje błąd (expr: syntax error
) w systemie macOS.Ok, oto moja droga.
na przykład
Używam tego w moich plikach dot
źródło
http://en.wikipedia.org/wiki/Uname
Wszystkie informacje, których kiedykolwiek będziesz potrzebować. Google to twój przyjaciel.
Służy
uname -s
do zapytania o nazwę systemu.Darwin
CYGWIN_...
LINUX
dla większościźródło
Podsystem Windows dla systemu Linux nie istniał, gdy zadano to pytanie. Dało to wyniki w moim teście:
Oznacza to, że potrzebujesz uname -r, aby odróżnić go od natywnego Linuksa.
źródło
Myślę, że nieznajoma odpowiedź jest bezkonkurencyjna, głównie pod względem czystości.
Chociaż wykonanie zajmuje absurdalnie dużo czasu, okazało się, że testowanie obecności określonych plików daje mi również dobre i szybsze wyniki, ponieważ nie wywołuję pliku wykonywalnego:
Więc,
[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running
po prostu używa szybkiego sprawdzania obecności pliku Bash. Ponieważ jestem teraz w systemie Windows, nie mogę powiedzieć ci żadnych konkretnych plików dla systemu Linux i Mac OS X z mojej głowy, ale jestem prawie pewien, że istnieją. :-)
źródło
Używaj tylko tego z wiersza poleceń, działa bardzo dobrze, dzięki Justin:
źródło
źródło