I have had relatively good success at writing portable, full-featured shell
shell scripts by using /bin/sh
, for example:
#!/bin/sh
trap 'echo "Error on line $LINENO"; exit 1' ERR
while read LINE
do
echo "+ $LINE"
done < file.txt
this works on BSD because /bin/sh
is typically an alias to ksh
$ ls -li /bin/{sh,ksh}
26768 -r-xr-xr-x 3 root bin 418612 Jun 18 17:41 /bin/ksh
26768 -r-xr-xr-x 3 root bin 418612 Jun 18 17:41 /bin/sh
While on MacOS and many Linux distros simply symlink /bin/sh
to bash
$ ls -li /bin/{sh,bash}
17170438 -rwxr-xr-x 1 root root 938832 Jul 18 2013 /bin/bash
17170540 lrwxrwxrwx 1 root root 4 Feb 19 12:42 /bin/sh -> bash
If these two conditions are true then I can use a relatively rich feature set common to both KSH and BASH. On Ubuntu the default shell only supports POSIX features. Is it still possible to write a cross-platform shell script that also incorporates error handling?
Edit (2014-08-18)
The solution I came up with was to auto-upgrade the script if the given shell doesn't understand the ERR trap
#!/bin/sh
trap 'echo "Error on line $LINENO"; exit 1' ERR || exec bash $0 "$@"
This allows me to write reasonably portable shell scripts that only require bash if the default shell doesn't support KSH features.
Best Answer
If you want to write a portable shell script you should stick with POSIX as that's the most reliable standard in the Unix world.
Relying in
/bin/sh
being anything but a Bourne shell is bad style and will likely break sooner or later.As POSIX doesn't support the
ERR
trap you have to manually add your error handler to any command you want it for, using||
. For example: