How to check if running in Cygwin, Mac or Linux?
Usually, uname
with its various options will tell you what environment you're running in:
pax> uname -aCYGWIN_NT-5.1 IBM-L3F3936 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwinpax> uname -sCYGWIN_NT-5.1
And, according to the very helpful schot
(in the comments), uname -s
gives Darwin
for OSX and Linux
for Linux, while my Cygwin gives CYGWIN_NT-5.1
. But you may have to experiment with all sorts of different versions.
So the bash
code to do such a check would be along the lines of:
unameOut="$(uname -s)"case "${unameOut}" in Linux*) machine=Linux;; Darwin*) machine=Mac;; CYGWIN*) machine=Cygwin;; MINGW*) machine=MinGw;; *) machine="UNKNOWN:${unameOut}"esacecho ${machine}
Note that I'm assuming here that you're actually running within CygWin (the bash
shell of it) so paths should already be correctly set up. As one commenter notes, you can run the bash
program, passing the script, from cmd
itself and this may result in the paths not being set up as needed.
If you are doing that, it's your responsibility to ensure the correct executables (i.e., the CygWin ones) are being called, possibly by modifying the path beforehand or fully specifying the executable locations (e.g., /c/cygwin/bin/uname
).
Here is the bash script I used to detect three different OS type (GNU/Linux, Mac OS X, Windows NT)
Pay attention
- In your bash script, use
#!/usr/bin/env bash
instead of#!/bin/sh
to prevent the problem caused by/bin/sh
linked to different default shell in different platforms, or there will be error like unexpected operator, that's what happened on my computer (Ubuntu 64 bits 12.04). - Mac OS X 10.6.8 (Snow Leopard) do not have
expr
program unless you install it, so I just useuname
.
Design
- Use
uname
to get the system information (-s
parameter). - Use
expr
andsubstr
to deal with the string. - Use
if
elif
fi
to do the matching job. - You can add more system support if you want, just follow the
uname -s
specification.
Implementation
#!/usr/bin/env bashif [ "$(uname)" == "Darwin" ]; then # Do something under Mac OS X platform elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then # Do something under GNU/Linux platformelif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then # Do something under 32 bits Windows NT platformelif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then # Do something under 64 bits Windows NT platformfi
Testing
- Linux (Ubuntu 12.04 LTS, Kernel 3.2.0) tested OK.
- OS X (10.6.8 Snow Leopard) tested OK.
- Windows (Windows 7 64 bit) tested OK.
What I learned
- Check for both opening and closing quotes.
- Check for missing parentheses and braces {}
References
Use uname -s
(--kernel-name
) because uname -o
(--operating-system
) is not supported on some Operating Systems such as Mac OS and Solaris. You may also use just uname
without any argument since the default argument is -s
(--kernel-name
).
The below snippet does not require bash (i.e. does not require #!/bin/bash
)
#!/bin/shcase "$(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
The below Makefile
is inspired from Git project (config.mak.uname
).
ifdef MSVC # Avoid the MingW/Cygwin sections uname_S := Windowselse # 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 painifeq ($(uname_S),Windows) CC := cl endififeq ($(uname_S),OSF1) CFLAGS += -D_OSF_SOURCEendififeq ($(uname_S),Linux) CFLAGS += -DNDEBUGendififeq ($(uname_S),GNU/kFreeBSD) CFLAGS += -D_BSD_ALLOCendififeq ($(uname_S),UnixWare) CFLAGS += -Wextraendif...
See also this complete answer about uname -s
and Makefile
.
The correspondence table in the bottom of this answer is from Wikipedia article about uname
. Please contribute to keep it up-to-date (edit the answer or post a comment). You may also update the Wikipedia article and post a comment to notify me about your contribution ;-)
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
OpenBSD
OpenBSD
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