Determine OS from a single command line operation
If I understood your problem correctly, then uname
is the ideal command. If it's any Unix-system (including OSX), it'll return the correct variable, and if it's Windows it'll return command not found or similar.
Command which will succeed on both windows and linux, but gives a different result
I still think echo "$PATH"
is the right idea here if you can base your decision on the output.
Since with a shell (bash
, tcsh
, ksh
, etc.) on linux and cmd.exe
or powershell
on Windows you will get very different results.
With a linux/etc. shell you will get a path string.
With cmd.exe
you will get "$PATH"
.
And with powershell
you will get the empty string.
That empty string result is technically valid for linux/etc. since you can have an empty path there but you can work around that by using "${PATH:-linux}"
instead which, for an empty (or unset) $PATH
variable on in a sh
-derived shell will get you linux
and will still get you an empty string from powershell
(though this fails for a csh
derived shell it seems).
Determine the OS version, Linux and Windows from Powershell
Aren't there environment variables you can view on the other platforms for the OS?
Get-ChildItem -Path Env:
Particularly, on Windows at least, there's an OS environment variable, so you should be able to accomplish this by using $Env:OS
.
Since some time has passed and the PowerShell Core (v6) product is GA now (the Core branding has been dropped as of v7), you can more accurately determine your platform based on the following automatic boolean variables:
$IsMacOS
$IsLinux
$IsWindows
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 -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
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}"
esac
echo ${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
).
How to detect the OS from a Bash script?
I think the following should work. I'm not sure about win32
though.
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
# Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
# POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
# I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
# ...
else
# Unknown.
fi
OS detecting makefile
There are many good answers here already, but I wanted to share a more complete example that both:
- doesn't assume
uname
exists on Windows - also detects the processor
The CCFLAGS defined here aren't necessarily recommended or ideal; they're just what the project to which I was adding OS/CPU auto-detection happened to be using.
ifeq ($(OS),Windows_NT)
CCFLAGS += -D WIN32
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
CCFLAGS += -D AMD64
else
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CCFLAGS += -D AMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CCFLAGS += -D IA32
endif
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
CCFLAGS += -D LINUX
endif
ifeq ($(UNAME_S),Darwin)
CCFLAGS += -D OSX
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CCFLAGS += -D AMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CCFLAGS += -D IA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CCFLAGS += -D ARM
endif
endif
Get Windows version in a batch file
Have you tried using the wmic
commands?
Try wmic os get version
This will give you the version number in a command line, then you just need to integrate into the batch file.
Related Topics
How to Run Multiple Programs in a Sequence
Bash -C Variable Does Not Get Assigned
Print Differences of File1 to File2 Without Deleting Anything from File2
Phusion Passenger Nginx Module Installer V3.0.17 Issue on Debian 6.0.5 Amd64 Due to Broken Package
Update Specific Field in Text File in Specific Line
How to Route Webcam Video to Virtual Video Device on Linux (Via Opencv)
How to Add Text After Last Pattern Match Using Ed
Allocating a Data Page in Linux with Nx Bit Turned Off
Script to Get User That Has Process with Most Memory Usage
How to Create a Bash Variable Like $Random
How to Merge Two Rows in a Same Row from a Text File in Linux Shell Script
How to Escape Unusual/Uniq Characters from Expect Scripts
How to Get the CPU Time for a Perl System Call
"Command Not Found" Piping a Variable to Cut When Output Stored in a Variable
Nginx Location Deny by File Extension Syntax