Windows / Cygwin과 Mac 및 Linux 모두에서 사용되는 쉘 스크립트가 있습니다. 버전마다 약간 다른 변수가 필요합니다.
쉘 / bash 스크립트가 Cygwin, Mac 또는 Linux에서 실행 중인지 어떻게 감지 할 수 있습니까?
답변
일반적으로 uname
다양한 옵션을 통해 어떤 환경에서 실행 중인지 알 수 있습니다.
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
그리고, 매우 도움이에 따라 schot
(코멘트에) uname -s
제공 Darwin
OSX과 Linux
내 Cygwin에서이 제공하는 동안, Linux 용 CYGWIN_NT-5.1
. 그러나 모든 종류의 다른 버전을 실험해야 할 수도 있습니다.
따라서 bash
이러한 검사를 수행 하는 코드는 다음과 같습니다.
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
echo ${machine}
여기서는 CygWin ( 쉘의 쉘) 내에서 실제로 실행 bash
중이므로 경로가 이미 올바르게 설정되어 있다고 가정합니다. 한 주석 작성자가 지적한 것처럼 bash
스크립트를 cmd
자체적으로 전달 하여 프로그램을 실행할 수 있으며, 필요 에 따라 경로가 설정되지 않을 수 있습니다.
당신이 경우에 하는 그 일을, 그것은 (즉, Cygwin에서 사람이)라고되고 올바른 실행을 보장하기 위해 귀하의 책임 가능성이 경로를 수정 사전 또는 전체 (예를 들어, 실행 파일 위치를 지정하여이다 /c/cygwin/bin/uname
).
답변
다음은 세 가지 OS 유형 (GNU / Linux, Mac OS X, Windows NT)을 감지하는 데 사용한 bash 스크립트입니다.
주의
- bash 스크립트 에서 다른 플랫폼의 다른 기본 쉘에 연결된 문제를 방지하기 위해
#!/usr/bin/env bash
대신 사용하십시오. 예기치 않은 연산자 와 같은 오류가 있습니다#!/bin/sh
/bin/sh
내 컴퓨터에서 발생한 합니다 (Ubuntu 64 비트 12.04). - Mac OS X 10.6.8 (Snow Leopard)에는
expr
설치하지 않으면 프로그램 이 없으므로 그냥 사용하십시오uname
.
디자인
uname
시스템 정보를 얻는 데 사용-s
매개 변수).- 사용
expr
및substr
문자열을 다루기 위해 를 . - 사용하다
if
elif
fi
일치하는 작업을 수행하는 데 . - 원하는 경우 시스템 지원을 추가 할 수 있습니다
uname -s
. 사양을 따르십시오 .
이행
#!/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
테스팅
- Linux (Ubuntu 12.04 LTS, Kernel 3.2.0)는 정상적으로 테스트되었습니다.
- OS X (10.6.8 Snow Leopard)는 정상적으로 테스트되었습니다.
- Windows (Windows 7 64 비트)에서 정상으로 테스트되었습니다.
내가 배운 것
- 여는 따옴표와 닫는 따옴표를 모두 확인하십시오.
- 괄호와 중괄호가 없는지 확인 {}
참고 문헌
- [1] uname-위키 백과
- [2] 쉘 스크립트 구문 오류 : 예기치 않은 파일 끝
- [3] Bash 스크립트에서 OS 감지
- [4] BASH 프로그래밍 소개 하우투
답변
사용 uname -s
( --kernel-name
) 때문에 uname -o
( --operating-system
)와 같은 일부 운영 체제에서 지원되지 않습니다 맥 OS 와 솔라리스 . 당신은 또한 바로 사용할 수 uname
있는 인수없이 기본 인자이기 때문에 -s
(--kernel-name
) .
아래 스 니펫은 필요하지 않습니다 세게 때리다(즉 필요하지 않음 #!/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
아래 Makefile
에서 영감 힘내 프로젝트 ( 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
...
및 에 대한 전체 답변을uname -s
Makefile
참조하십시오 .
이 답변의 맨 아래에있는 해당 표는 Wikipedia 기사에 대한 것uname
입니다. 최신 상태로 유지하십시오 (답변을 편집하거나 의견을 게시하십시오). Wikipedia 기사를 업데이트하고 의견을 게시하여 기여에 대해 알려주십시오. 😉
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
답변
Bash는 쉘 변수 OSTYPE을 설정합니다. 보낸 사람 man bash
:
bash가 실행중인 운영 체제를 설명하는 문자열로 자동 설정됩니다.
이것은 uname
새로운 프로세스를 시작할 필요가 없다는 점에서 작은 이점 이 있으므로 실행이 더 빠릅니다.
그러나 예상 값의 권위있는 목록을 찾을 수 없습니다. 우분투 14.04에서는 ‘linux-gnu’로 설정되어 있습니다. 다른 가치를 위해 웹을 긁어 냈습니다. 그 후:
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
별표는 일부 경우에 중요합니다. 예를 들어 OSX는 ‘darwin’뒤에 OS 버전 번호를 추가합니다. ‘win’값은 실제로 ‘win32’입니다. 아마도 ‘win64’가 있습니까?
아마도 우리는 여기에서 검증 된 값의 테이블을 채우기 위해 협력 할 수 있습니다.
- Linux Ubuntu ( WSL 포함 ) :
linux-gnu
- Cygwin 64 비트 :
cygwin
- Msys / MINGW (Windows 용 Git Bash) :
msys
(기존 항목과 다른 경우 값을 추가하십시오)
답변
Albert의 답변을 바탕으로 $COMSPEC
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
이렇게하면에 대한 Windows 이름의 $OS
변형을 구문 분석하고 uname
MINGW, Cygwin 등의 변형을 구문 분석하지 않아도됩니다 .
배경 : %COMSPEC%
명령 프로세서 (Windows 쉘)의 전체 경로를 지정하는 Windows 환경 변수입니다. 이 변수의 값은 일반적 %SystemRoot%\system32\cmd.exe
으로로 평가됩니다 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
uname -s 명령의 6 번째 문자가 “CYGWIN”인 경우 cygwin 시스템이 가정됩니다.
답변
좋아, 여기가 내 길이야
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 ^ $? ))
}
예 :
osis Darwin &&
{
log_debug Detect mac osx
}
osis Linux &&
{
log_debug Detect linux
}
osis -n Cygwin &&
{
log_debug Not Cygwin
}
내 도트 파일 에서 이것을 사용합니다