Archive for February, 2011

h1

Shell Tips 4: Safe coding by testing exit conditions

February 14, 2011

How testing works — avoiding unnecessary $?’s
People often want to test whether a command has worked or not, which is a good
thing. You often see code that uses the $? variable, which stores the exit code,
the success or failure, of the most recent instruction.

dosomething
if [ $? -eq 0 ]
then
echo "it worked"
else
echo "it failed"
fi

However, this is somewhat back-to-front. The “if” command’s primary use is to
test for the success or failure of a command. To test an abstract, boolean
function, it has to be evaluated and turned into an exit value, which is what the ‘test’
keyword does (and its equivalent, the square brackets). Therefore the code above can be simpified
into

if dosomething
then
echo "it worked"
else
echo "it failed"
fi

4.2 There is an even more compact way of writing this kind of code (and if you are not writing code this way,
you probably should be, especially if it is to be run by root, or to run unattended).

dosomething && echo "it worked"
dosomething || exit 1

The second form — try something, and quit on fail — is the more useful. It is more useful still if, instead of
quitting just quitting, it calls a function that tidies up, deleting temporary files and so on.

dosomething || my_exit_function

4.3 A particularly useful construct, often seen in well-written scripts is

cd /somewhere | exit

Why? Suppose you have code that says

cd /somewhere
rm -r *

…and suppose /somewhere doesn’t exist. Then the “rm” will remove everything from whatever directory
the script was previously in, which might well be the root directory!

h1

Shell Tips 2: Quote Unquote

February 14, 2011

There are three different kinds of quote: single quotes, double quote, and backticks. Single quotes

''

are true quotes and suspend all special characters except ‘ itself.

Double quote
"" suspend execution and filename expansion, but shell variables are still expanded.
Illustrating filename expansion:

MyList=*

will put a list of files in the variable $MyList, whereas

MyList="*"

will store an asterisk character in it.
If you just want to quote a common-or-garden string, always use single quotes.
Are double quotes useful? Very! If you double-quote all your variables (except
on the left of an assignment)…

"$LikeThis"

you can avoid a lot of problems.
Double quotes are useful in combination with backticks or or $() operator. The point of this gizmo is to take the
output of a command and turn it into a string. If a command produces output on multiple line, the
formatting gets lost. For instance

OutPut1=$(ls)

will store a list of files all in one line:

echo $OutPut1

produces

aFile anotherFile

whereas

OutPut2="$(ls)"

will maintain the formatting:

echo "$OutPut2"

produces

aFile
anotherFile

h1

Shell tips 5: External programmes are being run non-interactively.

February 14, 2011

Some external programmes, such as “fsck”
will pause for user input, which means a script suingthem cannot be run unattended. There is a usually
an options (such as “-y” for “yes to everything” to override that behaviour).

h1

Shell Tips 9: Testing $?

February 14, 2011

There is a built in shell variable $? which
gives the return value — the success or failure —
of the most recently executed command. (Functions and
builtins return such results, although we are usually interested in the
result of an executable).
Don’t do this:

someprocess someargument
if [ $? = 0 ]
then
echo "success"
fi

it can be more concisely written as:

if someprocess someargument
then
echo "success"
fi

Why? Note the lack of square brackets.
The “if” construct was originally designed to detect the
success or failure of a command, and the value for success
is 0. It was extended by the [] construct to do more
general boolean aalgebra, where 0 corresponds to false, and
non-zero to true–the other way round.
So in the first block of code, the command is retrutng
0 meaning success, which is then compared to 0 to turn it
into a boolean true or non-zer0, which is then autiomaticallly
converted back to a 0 by the left angle bracket!

h1

Shell Tips 8: Short Form Empty File Creation

February 14, 2011

” can be used instead of cat or echo in some shells, e.g to create an empty file

> emptyfile

rather than

echo '' > emptyfile"

h1

Shell Tips 10: The $$ Trick

February 14, 2011

The $$ temporary file trick. Writing files to /tmp has the disadvantage that it is
shared between all users and processes, leading to possuble clashed, overwrites etc.
$$ is an automatic shell variable containing the ID of the current process. If
a script creats temporary files which have its own name and process ID, the
resulting names will be highly unique. If the script is invoked more than
once, the PIDs will be different and so will the temp file names. This
is true even if it is being run simultaneously by different users or the same user.