4 ms·
Something to add to your 'bag-of-tricks' -- this was once handed down to me by a master by the name of .ike, as it was handed down to him before. Maybe you'd be
by buckie 12y ago
Something to add to your 'bag-of-tricks' -- this was once handed down to me by a master by the name of .ike, as it was handed down to him before. Maybe you'd be interested:
"The 3-finger Claw Technique" The sweetest 3 functions, ever.
shout() { echo "$0: $*" >&2; }
barf() { shout "$*"; exit 111; }
safe() { "$@" || barf "Cannot $*"; }
and always,
exit 0
I use these daily, they're extremely cross-platform friendly in any bourne-derived shell I've used in the last 4 years.
safexample.sh :
--
#!/bin/sh
shout() { echo "$0: $*" >&2; }
barf() { shout "$*"; exit 111; }
safe() { "$@" || barf "cannot $*"; }
# consider the following lines
safe cd /some/dir
safe tar xzvfp /my/big/tarball.tbz
exit 0
--
In the above example, using 'safe' suddenly gives the user the following special powers:
1. if `/some/dir` does not exist, the script will safely exit before that un-tarring does any damage.
2. the actual 'directory does not exist' will return to stderr for the script, (as opposed to just telling us the useless fact that the enclosing script failed).
Now bourne shell starts behaving like a modern language! (ala Python/Ruby tracebacks, Perl errors, etc…)
Additionally, if you 'exit 0' at the end, you can run non-safe operations, and always be guaranteed that if the shell exits, it was 'complete'.
An example:
# consider the following lines
safe cd /some/dir
tar xzvfp /my/big/tarball.tbz
Now, safe was removed from the un-tar command, right? So, imaging tarballs created by people using a Mac (with HFS+ and some filesystem-specific sticky bit somewhere in the filesystem which was tar'd up). Now, you un-tar it on some BSD or other NIX box, and tar complains as it goes- and exits non-zero. One way to handle this, is to consider the tar 'reliable', and not use safe for it.
Now, if we continue to be conscious of this simple safe/notsafe distinction with these scripts, they can be called by other safe scripts- and behave just like any respectable UNIX program!
Now, consider this crontab entry:
1 3 * * * someuser flock -k /tmp/safexample.lock /path/to/safexample.sh
If it fails, (for bad perms, no tarball to unpack, etc…) cron will actually have a reasonable message to email/log on failure!
Thanks to the noble efforts of the Clan of the White Lotus, these 3 functions originate during the late thirteenth century. The original author, William Baxter, explained that these three functions took 15 years to boil down to what they are- I believe that after mercilessly abusing them for several years myself…
Below is another example with more bits.
#!/bin/sh
shout() { echo "$0: $*" >&2; }
barf() { shout "$*"; exit 111; }
safe() { "$@" || barf "cannot $*"; }
for i in "before $@ after"
do
echo "arg <$i>"
done
for i in "before $* after"
do
echo "arg <$i>"
done
safe echo "this is ok"
safe echo "this is ok, too" || safe echo "so is this"
safe bad_echo "this is bad"
exit 0
- jzwinck 12y agoYou don't need to copy those boilerplate functions everywhere you go. Bash and others have "set -e" which will make the overall script exit with an error if one of its commands returns an error. Also useful is "set -u" to detect the use of unset variables (though some people write shell scripts which depend on those, so it's not as universally applicable). Try writing "set -eu" as the first line of your shell scripts. It's sort of like compiling with "-Wall -Werror"--not the default but perhaps should have been.
- signa11 12y agosource: http://permalink.gmane.org/gmane.org.user-groups.bsd.nycbug/8716 http://permalink.gmane.org/gmane.org.user-groups.bsd.nycbug/... edit: or the way more useful entire nifty(1) gmane-thread http://thread.gmane.org/gmane.org.user-groups.bsd.nycbug/8714 http://thread.gmane.org/gmane.org.user-groups.bsd.nycbug/871...