My examples for this post are largely from the excellent Bash by example, part 3 post on IBM. Refer to The Advanced Bash Scripting Guide sections 7.1 Test Constructs and 7.3 Other Comparison Operators for details on the comparisons used. The examples shown were tested on Solaris 5.10.
Correct number of arguments
Verbose:
if [ $# -ne 2 ] then echo "Please specify ebuild file and unpack, compile or all" exit 1 fiTerse:
[ $# == 2 ] || {echo "Please specify ebuild file and unpack, compile or all"; exit 1;}
This works because Bash short-circuits. That is for A || B we only execute B if A is true, if A is false the result is already known to be false and we don't have to run B at all.
NOTE: Example above was corrected to {} instead of (); this is important as you do NOT want a subshell or else exit won't actually break out of your script. { commands; } doesn't create a subshell and thus works as expected.
Set a variable to a default value if unset
Verbose:
if [ -z "$DISTDIR" ] then # set DISTDIR to /usr/src/distfiles if not already set DISTDIR=/usr/src/distfiles fiTerse:
# set DISTDIR to /usr/src/distfiles if not already set [ -z "$DISTDIR" ] && DISTDIR=/usr/src/distfilesThis time we use short-circuited &&: if DISTDIR is null the first part is true and the second part executes.
Terse option 2:
[ -n "$DISTDIR" ] || DISTDIR=/usr/src/distfilesIf DISTDIR is NOT null the first part is true and we skip the second. If DISTDIR is null the first part is false and we have to execute the second part.
Make sure we have a clean directory to work in
Verbose:
if [ -d ${WORKDIR} ] then rm -rf ${WORKDIR} fi mkdir ${WORKDIR}Terse:
[ ! -d ${WORKDIR} ] || rm -rf ${WORKDIR} mkdir ${WORKDIR}Note the addition of ! in the terse version: we want the first part to check false if the directory exists to ensure the second part executes, removing the directory.
Closing Notes
We can obviously continue with just about every if statement that only has one or two short actions.
A huge advantage of the verbose versions is that people are more used to them. Terse is nice in some ways but I strongly suspect more developers understand if [ blah ] then echo exit fi than [ something ] || (echo; exit). There may be additional ramifications to the reduction; I'm not Bash guru enough to say they are exact equivalents.
Another possible advantage to the short-form is it makes error checking easy enough to validate commands we usually just assume to work. For example, don't just tar xzf whatever and assume it unpacked, actually check it worked rather than detecting the failure later when some subsequent step failed.
Anyway, I'm far from ready to suggest that the terse form should be used everywhere but it is a useful tool to have for one-liners in the terminal and possibly to shorten scripts that have piles of dead simple if/then checks.
4 comments:
Given that we need to write bash script in vim or vi editor I would rather go for readability and to me verbose is the choice. but yes you made some point for terse version as well.
Javin
basic networking command in unix
"That is for A || B we only execute B if A is true, if A is false the result is already known to be false and we don't have to run B at all."
Ah, no. If A is false, B must be evaluated, because false || true is true.
"That is for A && B we only execute B if A is true, if A is false the result is already known to be false and we don't have to run B at all."
is correct.
{echo "Please specify ebuild file and unpack, compile or all"; exit 1;}
This is exactly what I was looking for, thank you. However, I should note a space is required on the inside of the braces.
"Great article! The comparison between terse and verbose conditional execution in Bash is very helpful. I appreciate the clear examples that illustrate when to use each style. This will definitely improve my scripting efficiency!"
Digital Marketing Course In Hyderabad
Post a Comment