Home » Debian, How-to, Linux, Shell, Ubuntu

Shell error handling

23 March 2009 No Comment

Today we will talk about shell error handling. Almost weekly I’m writing new shell scripts for me or my customers and in this time I learned something very valuable: writing scripts without error handling is like running windows, expect at unexpected. Let’s take the following example:

#!/bin/sh
 
CHROOT=$1
[ ... snip code ... ]
 
rm -rf $CHROOT/

Oops … This is the most bad thing what can happen, but is a very real and possible thing.

Errors can be handle in various ways, but in this article I will present you my methods to deal with the errors in shell.

Setting -e to your shell

Using set -e in your shell script is most easy way to handling errors. Just add set -e to your shell script and if you have any command error your script will stop running.

#!/bin/sh
set -e

Now you can handle errors of any program what doesn’t exit with error code 0. Also if you want to don’t check for every error then you use set +e

1
2
3
4
5
6
7
#!/bin/sh
set -e
command1
command2
set +e
command3
command4

set -e is equivalet with the following piece of code added after each command

command
if [ “$?”-ne 0]; then
echo “command failed”;
exit 1;
fi

You can also use this type of code to do the same thing

command || { echo “command failed”; exit 1; }

Using if

In some cases, when you expect at an error code and you cannot use set -e then you should check for this error and get the proper action based on error code.

command
if [ “$?”-ne 127]; then
echo “command not found”;
echo “that means the package was not installed and we should use command2”
command2
fi

$? returns the error code of the last executed command.

Using trap

The trap statement catches the exit signals of the applications and can execute a code before exit. Syntax is:

trap [COMMANDS] [SIGNALS]

trap will catch the configured signals and if one of signals is DEBUG the command will be executed after every command. The next example will print “Catched” if you will try to press Ctrl+C or if you kill the program with SIGTERM or SIGKILL

1
2
3
4
5
6
7
8
#!/bin/sh
 
trap "echo Catched !!!!; exit" SIGINT SIGTERM SIGKILL
 
while true
do
        sleep 60
done

Now just send SIGKILL or press CTRL+C …

Trap is very useful when you want to clean temproary files or other things at an unexpected user abort.

Error codes

ERROR CODE Meaning
1 general error
2 builtins return an exit status of 2 to indicate incorrect usage.
126 Command cannot be executed
127 Command not found
128+N Command exited with Signal N
130 Command exited with Ctrl+C
255 exist status out of range

Builtin bash test parameters.

Sometimes we need to know if a file exists or if it is a symbolic link. Bash shell have several bultin test commands what can be used.
-a file True if file exists.
-b file True if file exists and is a block special file.
-c file True if file exists and is a character special file.
-d file True if file exists and is a directory.
-e file True if file exists.
-f file True if file exists and is a regular file.
-g file True if file exists and is set-group-id.
-h file True if file exists and is a symbolic link.
-k file True if file exists and its ‘‘sticky’’ bit is set.
-p file True if file exists and is a named pipe (FIFO).
-r file True if file exists and is readable.
-s file True if file exists and has a size greater than zero.
-t fd True if file descriptor fd is open and refers to a terminal.
-u file True if file exists and its set-user-id bit is set.
-w file True if file exists and is writable.
-x file True if file exists and is executable.
-O file True if file exists and is owned by the effective user id.
-G file True if file exists and is owned by the effective group id.
-L file True if file exists and is a symbolic link.
-S file True if file exists and is a socket.
-N file True if file exists and has been modified since it was last read.

How we can use this builtin test commands.

if [ -f /var/log/syslog ]; then
  grep kerneld /var/log/sysylog
fi

Other useful things

sh -x script writes each command on stderr after was executed
sh -n script checks for syntax errors without executing
sh -v script writes each command on stderr before running
sh -u script gives an error message when undefined variables are used.

Good Luck!


Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.