Script doesn't work when it is run using '#!/bin/sh'
Solution 1:
Your friend on another computer probably uses an OS which has /bin/sh
linked to /bin/bash
. In Ubuntu (actually, Debian and most Debian derivatives), /bin/sh
is not linked to /bin/bash
, but to /bin/dash
, which doesn't support many bash
-specific features, but is considerably faster.
On Arch Linux:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Sep 28 15:26 /bin/sh -> bash
On Ubuntu:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 19 2014 /bin/sh -> dash
The right thing to do
If you use a shebang, mean it. Since your script contains bash
-isms, use /bin/bash
in the shebang. Or write portable, POSIX-compliant code.
You can speed up this process by using the checkbashisms
program mentioned in this LWN article. It's part of the devscripts
package, so install it first:
sudo apt-get install devscripts
Thus:
checkbashisms /path/to/script.sh || sed -i '1 s;/bin/sh;/bin/bash;' /path/to/script.sh
You can convert this to a script (say convert.sh
):
#! /bin/sh
for i
do
checkbashisms "$i"
if [ $? = "1" ]
then
sed -i '1 s;/bin/sh;/bin/bash;' "$i"
fi
done
The specific return code of 1
means that checkbashisms
found a possible bash
ism, and other return values indicate other problems (file not readable, missing shebang, etc.), so we can check for that particular return value.
And then call it with:
./convert.sh /path/to/first/script.sh /path/to/second/script.sh
# or
./convert.sh *.sh
# or
find . -iname '*.sh' -exec ./convert.sh {} +
The wrong thing to do
Replace /bin/sh
with a symbolic link to /bin/bash
.
Recommended reading:
-
Bashism - compares
bash
anddash
syntax and shows changes needed. -
Dash as
/bin/sh
- similar.