Câu trả lời:
Thông thường, uname
với các tùy chọn khác nhau sẽ cho bạn biết bạn đang chạy trong môi trường nào:
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
Và, theo rất hữu ích schot
(trong các bình luận), uname -s
cung cấp Darwin
cho OSX và Linux
cho Linux, trong khi Cygwin của tôi cung cấp CYGWIN_NT-5.1
. Nhưng bạn có thể phải thử nghiệm với tất cả các loại phiên bản khác nhau.
Vì vậy, bash
mã để thực hiện kiểm tra như vậy sẽ nằm dọc theo dòng:
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
echo ${machine}
Lưu ý rằng tôi giả sử ở đây rằng bạn thực sự đang chạy trong CygWin ( bash
vỏ của nó) vì vậy các đường dẫn đã được thiết lập chính xác. Như một người bình luận lưu ý, bạn có thể chạy bash
chương trình, truyền kịch bản từ cmd
chính nó và điều này có thể dẫn đến các đường dẫn không được thiết lập khi cần thiết.
Nếu bạn đang làm điều đó, bạn có trách nhiệm đảm bảo các tệp thực thi chính xác (nghĩa là các CygWin) đang được gọi, có thể bằng cách sửa đổi đường dẫn trước hoặc chỉ định đầy đủ các vị trí thực thi (ví dụ /c/cygwin/bin/uname
:).
MINGW32_NT-6.1
. Ngoài ra, không có /cygdrive
tiền tố, chỉ /c
dành cho C:
.
How can a shell/bash script detect ...
và câu trả lời khác.
uname -s
kết thúc cuộc gọi bất cứ điều gì uname
đầu tiên trong đường dẫn hiện tại của bạn, mà trên hệ thống của tôi hóa ra là phiên bản được cài đặt geda
trả về văn bản WindowsNT
. Nó cũng có thể là phiên bản MinGW như được mô tả ở trên. Một phát hiện đáng tin cậy cho cygwin không được dựa vào đường dẫn được đặt một cách thích hợp, IMO. Do đó, $(uname -s)
nên được thay đổi $(/bin/uname -s)
để phát hiện cygwin.
#!/usr/bin/env bash
thay vì #!/bin/sh
để ngăn sự cố do /bin/sh
liên kết với lớp vỏ mặc định khác nhau trong các nền tảng khác nhau hoặc sẽ có lỗi như toán tử bất ngờ , đó là những gì đã xảy ra trên máy tính của tôi (Ubuntu 64 bit 12.04).expr
chương trình trừ khi bạn cài đặt nó, vì vậy tôi chỉ sử dụng uname
.uname
để có được thông tin hệ thống ( -s
tham số).expr
và substr
để đối phó với chuỗi.if
elif
fi
để làm công việc phù hợp.uname -s
đặc điểm kỹ thuật.#!/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)"
là lạ một chút. Có nhiều cách hay hơn để làm điều đó, ví dụ : if [ `uname -s` == CYGWIN* ]; then
. Đọc nó: nếu uname -s
bắt đầu với CYGWIN thì ...
if [[ $(uname -s) == CYGWIN* ]]; then
uname -s
sẽ mang lại thứ gì đó không phải là "Linux" không?
Sử dụng uname -s
( --kernel-name
) vì uname -o
( --operating-system
) không được hỗ trợ trên một số Hệ điều hành như Mac OS và Solaris . Bạn cũng có thể sử dụng uname
mà không có bất kỳ đối số nào vì đối số mặc định là -s
( --kernel-name
).
Đoạn mã dưới đây không yêu cầu bash(tức là không yêu cầu #!/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
Dưới đây Makefile
được lấy cảm hứng từ dự án 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
...
Xem thêm câu trả lời đầy đủ về uname -s
vàMakefile
.
Bảng tương ứng ở dưới cùng của câu trả lời này là từ bài viết trên Wikipedia vềuname
. Hãy đóng góp để giữ cho nó cập nhật (chỉnh sửa câu trả lời hoặc gửi bình luận). Bạn cũng có thể cập nhật bài viết Wikipedia và đăng bình luận để thông báo cho tôi về đóng góp của bạn ;-)
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
(để đặt các biến môi trường như $PATH
- bình luận để cung cấp từ khóa tìm kiếm cho hậu thế).
uname -sr
và so sánh với Linux*Microsoft)
trước đây Linux*)
.
Bash đặt biến shell OSTYPE. Từ man bash
:
Tự động đặt thành một chuỗi mô tả hệ điều hành mà bash đang thực thi.
Điều này có một lợi thế rất nhỏ uname
ở chỗ nó không yêu cầu khởi chạy một quy trình mới, vì vậy sẽ nhanh hơn để thực hiện.
Tuy nhiên, tôi không thể tìm thấy một danh sách có thẩm quyền của các giá trị dự kiến. Đối với tôi trên Ubuntu 14.04, nó được đặt thành 'linux-gnu'. Tôi đã quét web cho một số giá trị khác. Vì thế:
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
Dấu hoa thị rất quan trọng trong một số trường hợp - ví dụ OSX nối thêm số phiên bản HĐH sau 'darwin'. Giá trị 'win' thực sự là 'win32', tôi được cho biết - có thể có 'win64'?
Có lẽ chúng ta có thể làm việc cùng nhau để đưa ra một bảng các giá trị được xác minh ở đây:
linux-gnu
cygwin
msys
(Vui lòng nối thêm giá trị của bạn nếu nó khác với các mục hiện có)
env | grep OSTYPE
, nhưng bạn sẽ thấy nó dướiset | grep OSTYPE
OSTYPE
biến Bash (conftypes.h) được định cấu hình tại thời điểm xây dựng bằng cách sử dụng bản sao chính xác của OS
biến automake (Makefile.in) . Người ta có thể tham khảo tệp lib / config.sub của automake cho tất cả các loại có sẵn.
Để xây dựng câu trả lời của Albert, tôi muốn sử dụng $COMSPEC
để phát hiện 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
Điều này tránh phân tích các biến thể của tên Windows cho $OS
và phân tích các biến thể uname
như MINGW, Cygwin, v.v.
Bối cảnh: %COMSPEC%
là biến môi trường Windows chỉ định đường dẫn đầy đủ đến bộ xử lý lệnh (hay còn gọi là vỏ Windows). Giá trị của biến này là điển hình %SystemRoot%\system32\cmd.exe
, thường ước tính 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
Nếu 6 ký tự đầu tiên của lệnh uname -s là "CYGWIN", thì một hệ thống cygwin được giả sử
if [ `uname -s` == CYGWIN* ]; then
trông tốt hơn và làm việc như nhau.
[[ $(uname -s) == CYGWIN* ]]
. Cũng lưu ý rằng các biểu thức chính quy mở rộng chính xác hơn trong trường hợp của chúng tôi : [[ $(uname -s) =~ ^CYGWIN* ]]
.
expr substr $(uname -s) 1 6
đưa ra một lỗi ( expr: syntax error
) trên macOS.
Ok, đây là cách của tôi.
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 ^ $? ))
}
ví dụ
osis Darwin &&
{
log_debug Detect mac osx
}
osis Linux &&
{
log_debug Detect linux
}
osis -n Cygwin &&
{
log_debug Not Cygwin
}
Tôi sử dụng điều này trong dotfiles của tôi
http://en.wikipedia.org/wiki/Uname
Tất cả các thông tin bạn sẽ cần. Google là bạn của bạn.
Sử dụng uname -s
để truy vấn tên hệ thống.
Darwin
CYGWIN_...
LINUX
đối với hầu hếtHệ thống con Windows cho Linux không tồn tại khi câu hỏi này được hỏi. Nó đã cho những kết quả này trong thử nghiệm của tôi:
uname -s -> Linux
uname -o -> GNU/Linux
uname -r -> 4.4.0-17763-Microsoft
Điều này có nghĩa là bạn cần uname -r để phân biệt với Linux nguyên gốc.
Tôi đoán câu trả lời uname là vô địch, chủ yếu là về sự sạch sẽ.
Mặc dù phải mất một thời gian vô lý để thực thi, tôi thấy rằng việc kiểm tra sự hiện diện của các tệp cụ thể cũng mang lại cho tôi kết quả tốt và nhanh hơn, vì tôi không yêu cầu thực thi:
Vì thế,
[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running
chỉ cần sử dụng một kiểm tra hiện diện tập tin Bash nhanh chóng. Vì tôi đang sử dụng Windows ngay bây giờ, tôi không thể cho bạn biết bất kỳ tệp cụ thể nào dành cho Linux và Mac OS X từ đầu của tôi, nhưng tôi khá chắc chắn rằng chúng tồn tại. :-)
Chỉ sử dụng điều này từ dòng lệnh hoạt động rất tốt, nhờ Justin:
#!/bin/bash
################################################## #########
# Bash script to find which OS
################################################## #########
OS=`uname`
echo "$OS"