Difference between revisions of "Bash disaster prevention"
Line 16: | Line 16: | ||
On one day, you simply forget to insert the usb key, before running the command: | On one day, you simply forget to insert the usb key, before running the command: | ||
<nowiki> | |||
</nowiki><pre><nowiki> | |||
loadmusic.bash : line 2: cd: /mnt/usbstick/todaysmusic: No such file or directory | |||
Done! | |||
</nowiki></pre> | |||
What happens here. Bash tries to change directory to /mnt/usbstick/todaysmusic , but can't. Does it stop there? Not unless we ask it to. It simply forgets what happened and executes the next command, namely <tt>rm -rf</tt> and innocently deletes ALL your digital music albums! (And we don't waste time on useless stuff like backups!!) | |||
==Error handling== | |||
{{wbox|Never, ever use dangerous commands like rm -rf (or rm by itself for that matter) or mv in a script that doesn't have a proper error handler.}} | |||
Whenever there is the potential for pitfalls like the above, use some form of general error handler to at least tell the script to exit without trying the rest of the commands. | |||
#!/bin/bash | |||
## End of error handling | |||
function handle { | |||
echo "Error" | |||
exit 1 | |||
} | |||
trap handle ERR | |||
## End of error handling | |||
cd /mnt/usbstick/todaysmusic # Go to the appropriate folder | |||
rm -rf #Delete all the old files | |||
cp -r /home/alex/music/$1 . | |||
echo 'Done!' | |||
which will execute the function <nowiki> | |||
</nowiki><pre><nowiki> | |||
handle() | |||
</nowiki></pre> as soon as it encounters and error. And inside <nowiki> | |||
</nowiki><pre><nowiki> | |||
handle() | |||
</nowiki></pre>, we have <nowiki> | |||
</nowiki><pre><nowiki> | |||
exit | |||
</nowiki></pre>, so there's no danger of bash trying to be smart. | |||
==More useful error handling== | |||
{{mbox|trap type of error handling is useful for preventing disasters. For more graceful error handling, the [[wikipedia:return value|return value]] of each individual command can be checked. }} |
Revision as of 01:09, 12 May 2006
Like any other versatile tool, consequences of misusing of UNIX scripting can be disasterous. It often helps to save the day
A horror story
You listen to music and have built up a quite extensive library of digital music in your computer under the directory /home/alex/music. Everyday, you copy a folder from under music folder (e.g. beatles/yellowsubmarine) to your MP3 player, which appears as a usb drive (say /mnt/usbstick). You write a small script called loadmusic.bash and save it in /home/alex/,
#!/bin/bash cd /mnt/usbstick/todaysmusic # Go to the appropriate folder rm -rf #Delete all the old files cp -r /home/alex/music/$1 . echo 'Done!'
and call it as
$ loadmusic.bash yellowsubmarine
On one day, you simply forget to insert the usb key, before running the command:
loadmusic.bash : line 2: cd: /mnt/usbstick/todaysmusic: No such file or directory Done!
What happens here. Bash tries to change directory to /mnt/usbstick/todaysmusic , but can't. Does it stop there? Not unless we ask it to. It simply forgets what happened and executes the next command, namely rm -rf and innocently deletes ALL your digital music albums! (And we don't waste time on useless stuff like backups!!)
Error handling
Never, ever use dangerous commands like rm -rf (or rm by itself for that matter) or mv in a script that doesn't have a proper error handler.
Whenever there is the potential for pitfalls like the above, use some form of general error handler to at least tell the script to exit without trying the rest of the commands.
- !/bin/bash
- End of error handling
function handle {
echo "Error" exit 1
} trap handle ERR
- End of error handling
cd /mnt/usbstick/todaysmusic # Go to the appropriate folder rm -rf #Delete all the old files cp -r /home/alex/music/$1 . echo 'Done!'
which will execute the function
handle()
as soon as it encounters and error. And inside
handle()
, we have
exit
, so there's no danger of bash trying to be smart.