Saya memiliki skrip shell yang digunakan pada Windows / Cygwin dan Mac dan Linux. Perlu variabel yang sedikit berbeda untuk setiap versi.
Bagaimana skrip shell / bash mendeteksi apakah skrip ini berjalan di Cygwin, di Mac atau di Linux?
sumber
Saya memiliki skrip shell yang digunakan pada Windows / Cygwin dan Mac dan Linux. Perlu variabel yang sedikit berbeda untuk setiap versi.
Bagaimana skrip shell / bash mendeteksi apakah skrip ini berjalan di Cygwin, di Mac atau di Linux?
Biasanya, uname
dengan berbagai opsi akan memberi tahu Anda di lingkungan mana Anda menjalankan:
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
Dan, menurut sangat membantu schot
(dalam komentar), uname -s
memberi Darwin
untuk OSX dan Linux
untuk Linux, sedangkan Cygwin saya memberi CYGWIN_NT-5.1
. Tetapi Anda mungkin harus bereksperimen dengan semua versi yang berbeda.
Jadi bash
kode untuk melakukan pemeriksaan seperti itu ada di sepanjang baris:
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
echo ${machine}
Perhatikan bahwa saya berasumsi di sini bahwa Anda benar-benar berjalan di dalam CygWin ( bash
cangkang itu) sehingga jalur seharusnya sudah diatur dengan benar. Seperti yang dicatat oleh satu komentator, Anda dapat menjalankan bash
program, melewati skrip, dari skrip cmd
itu sendiri dan ini dapat mengakibatkan jalur tidak diatur sesuai kebutuhan.
Jika Anda sedang melakukan itu, itu tanggung jawab Anda untuk memastikan executable yang benar (yaitu, orang-orang Cygwin) dipanggil, mungkin dengan memodifikasi jalan terlebih dahulu atau sepenuhnya menentukan lokasi executable (misalnya, /c/cygwin/bin/uname
).
MINGW32_NT-6.1
. Juga, tidak ada/cygdrive
awalan, hanya/c
untukC:
.How can a shell/bash script detect ...
dan yang lainnya tidak.uname -s
akhirnya memanggil apa pununame
yang pertama di jalur Anda saat ini, yang pada sistem saya ternyata merupakan versi yang diinstal dengangeda
yang mengembalikan teksWindowsNT
. Namun bisa juga versi MinGW seperti dijelaskan di atas. Deteksi yang dapat diandalkan untuk cygwin tidak harus bergantung pada jalur yang ditetapkan dengan tepat, IMO. Karena itu,$(uname -s)
harus diubah$(/bin/uname -s)
untuk mendeteksi cygwin.Berikut ini skrip bash yang saya gunakan untuk mendeteksi tiga tipe OS yang berbeda (GNU / Linux, Mac OS X, Windows NT)
Perhatian
#!/usr/bin/env bash
alih-alih#!/bin/sh
untuk mencegah masalah yang disebabkan oleh/bin/sh
tertaut ke shell default yang berbeda di platform yang berbeda, atau akan ada kesalahan seperti operator yang tidak terduga , itulah yang terjadi di komputer saya (Ubuntu 64 bit 12,04).expr
program kecuali Anda menginstalnya, jadi saya gunakan sajauname
.Rancangan
uname
untuk mendapatkan informasi sistem (-s
parameter).expr
dansubstr
untuk menangani string.if
elif
fi
untuk melakukan pekerjaan yang cocok.uname -s
spesifikasinya.Penerapan
Pengujian
Apa yang saya pelajari
Referensi
sumber
[ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]
."$(expr substr $(uname -s) 1 5)"
agak aneh. Ada cara yang lebih cantik untuk melakukan itu, misalnya:if [ `uname -s` == CYGWIN* ]; then
. Baca: jikauname -s
dimulai dengan CYGWIN maka ...if [[ $(uname -s) == CYGWIN* ]]; then
uname -s
akan menghasilkan sesuatu selain "Linux"?Gunakan
uname -s
(--kernel-name
) karenauname -o
(--operating-system
) tidak didukung pada beberapa Sistem Operasi seperti Mac OS dan Solaris . Anda juga dapat menggunakan hanyauname
tanpa argumen karena argumen defaultnya adalah-s
(--kernel-name
).Cuplikan di bawah ini tidak perlu pesta(Yaitu tidak memerlukan
#!/bin/bash
)Di bawah
Makefile
ini terinspirasi dari proyek Git (config.mak.uname
) .Lihat juga jawaban lengkap ini tentang
uname -s
danMakefile
.Tabel korespondensi di bagian bawah jawaban ini adalah dari artikel Wikipedia tentang
uname
. Silakan berkontribusi agar tetap mutakhir (edit jawaban atau kirim komentar). Anda juga dapat memperbarui artikel Wikipedia dan mengirim komentar untuk memberi tahu saya tentang kontribusi Anda ;-)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
sumber
~/.profile
(untuk mengatur variabel lingkungan seperti$PATH
- berkomentar untuk menyediakan kata kunci pencarian untuk anak cucu).uname -sr
dan membandingkan denganLinux*Microsoft)
sebelumnyaLinux*)
.Bash menetapkan variabel shell OSTYPE. Dari
man bash
:Ini memiliki keuntungan kecil
uname
karena tidak perlu meluncurkan proses baru, jadi akan lebih cepat untuk dijalankan.Namun, saya tidak dapat menemukan daftar nilai yang diharapkan yang otoritatif. Bagi saya di Ubuntu 14,04 diatur ke 'linux-gnu'. Saya telah mengorek web untuk beberapa nilai lainnya. Karenanya:
Tanda bintang penting dalam beberapa hal - misalnya OSX menambahkan nomor versi OS setelah 'darwin'. Nilai 'win' sebenarnya adalah 'win32', saya diberitahu - mungkin ada 'win64'?
Mungkin kita dapat bekerja sama untuk mengisi tabel nilai yang diverifikasi di sini:
linux-gnu
cygwin
msys
(Harap tambahkan nilai Anda jika berbeda dari entri yang ada)
sumber
env | grep OSTYPE
, tetapi Anda akan melihatnya di bawahset | grep OSTYPE
OSTYPE
variabel Bash (conftypes.h) dikonfigurasikan pada waktu build menggunakan salinan tepat dariOS
variabel automake (Makefile.in) . Seseorang dapat berkonsultasi file lib / config.sub automake untuk semua jenis yang tersedia.Untuk membangun berdasarkan jawaban Albert, saya suka menggunakan
$COMSPEC
untuk mendeteksi Windows:Ini menghindari parsing varian nama Windows untuk
$OS
, dan parsing varianuname
seperti MINGW, Cygwin, dll.Latar Belakang:
%COMSPEC%
adalah variabel lingkungan Windows yang menetapkan jalur lengkap ke prosesor perintah (alias shell Windows). Nilai variabel ini biasanya%SystemRoot%\system32\cmd.exe
, yang biasanya dievaluasi menjadiC:\Windows\system32\cmd.exe
.sumber
Jika 6 karakter pertama dari perintah uname -s adalah "CYGWIN", sebuah sistem cygwin diasumsikan
sumber
if [ `uname -s` == CYGWIN* ]; then
terlihat lebih baik dan berfungsi sama.[[ $(uname -s) == CYGWIN* ]]
. Perhatikan juga bahwa ekspresi reguler diperpanjang lebih tepat dalam kasus kami:[[ $(uname -s) =~ ^CYGWIN* ]]
.expr substr $(uname -s) 1 6
memberikan kesalahan (expr: syntax error
) pada macOS.Ok, ini cara saya.
misalnya
Saya menggunakan ini di dotfiles saya
sumber
http://en.wikipedia.org/wiki/Uname
Semua info yang Anda butuhkan. Google adalah temanmu.
Gunakan
uname -s
untuk menanyakan nama sistem.Darwin
CYGWIN_...
LINUX
untuk sebagian besarsumber
Subsistem Windows untuk Linux tidak ada saat pertanyaan ini diajukan. Ini memberikan hasil ini dalam pengujian saya:
Ini berarti Anda perlu uname -r untuk membedakannya dari Linux asli.
sumber
Saya kira jawaban yang sama tidak terkalahkan, terutama dalam hal kebersihan.
Meskipun butuh waktu yang konyol untuk mengeksekusi, saya menemukan bahwa pengujian untuk kehadiran file tertentu juga memberi saya hasil yang lebih baik dan lebih cepat, karena saya tidak menggunakan executable:
Begitu,
[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running
hanya menggunakan pemeriksaan kehadiran file Bash cepat. Karena saya menggunakan Windows sekarang, saya tidak dapat memberi tahu Anda file spesifik untuk Linux dan Mac OS X dari kepala saya, tetapi saya cukup yakin mereka ada. :-)
sumber
Gunakan ini hanya dari baris perintah yang bekerja dengan sangat baik, terima kasih kepada Justin:
sumber
sumber