Reputation: 1647
I inherited some shell scripts written to do automated performance testing without having any shell scripting knowledge. I skimmed through a few guides and played around with the language until I could do my project. It mostly went well, but I'm stuck on something I absolutely have not been able to find an answer to anywhere else.
Part of the old code ssh's into a server used in the testing with a script as an argument. I need this script do do different things on Windows and Linux. My best solution so far is to grep for Cygwin in uname -a's output, and if found, do the Windows code.
Unfortunately the script is going belly up both when passed via ssh, and when executed through Cygwin on the Windows system.
#!/bin/bash
if [ `uname -a | grep "Cygwin"` ]; then
echo "ARRGG WINDOWS!"
else
echo "Some Linux command."
fi
yields:
./test.sh: line 2: [: too many arguments
and then branches to the not-windows logic. The same thing appears to run fine on any Linux distribution I've tried.
I'm left with three questions. Why am I getting this exception, what are some good ways for me to get answers to hyper-specific questions like this (intersection between shell scripting, Cygwin, ssh, and one error) besides Googling, and is there a better, more canonical way to test for platform?
Thanks for your time, and I'll be happy to provide any additional info that will help.
The troublesome clause was copied verbatim, the rest was made up for SO.
Upvotes: 1
Views: 1241
Reputation: 4418
I tried your command, it executed without error on bash 4.2.37.
It will also work without the square brackets or back-ticks -- if
tests the return code of the next command... you can use the test
command, which can also be spelled [
, but it will also work with the return code of grep
or even :
which is always true.
#!/bin/bash
if uname -a | grep Cygwin > /dev/null; then
echo "ARRGG WINDOWS!"
else
echo "Some Linux command."
fi
Note, there is also a bash environment variable $OSTYPE
which will be linux-gnu
under Linux.
There's an in-depth discussion here: Detect the OS from a Bash script
Upvotes: 2
Reputation: 754560
The output for uname -a
on Cygwin will be many words including Cygwin
. Each word will be an argument to test
(aka [
). Hence the complaint. You probably want:
case "$(uname -a)" in
(*Cygwin*) echo "Oh bother!";;
(*) echo "Phew!";;
esac
or:
if [ -n "$(uname -a | grep Cygwin)" ]
then echo "Oh bother!"
else echo "Phew!"
fi
or:
if [ $(uname) = Cygwin ]
then echo "Oh bother!"
else echo "Phew!"
fi
This gets either Cygwin or Linux — or Darwin on Mac OS X, and equivalent names on AIX, Solaris, HP-UX — and avoids the multiple arguments issue and only runs one command instead of two.
Upvotes: 2