You've been asked to copy some jpg files to a USB disk overnight. That's easy enough - a cron job and a simple "cp -a" will do that.
But there is so much that could go wrong, isn't there? There might not be any files to copy or there might not be room on the USB disk. Somebody might have changed permissions on files or directories alreasdy in place, preventing overwrite with updated images.
Maybe your first thought was just to send all the output to a file that might get printed or mailed for someone to look at. That's easy:
#!/bin/bash cd /Pictures cp -av *jpg /TINYUSB > /tmp/report 2>&>1
Though that could be a mighty long report and if nothing went wrong, who cares?
You could just capture the error output.
#!/bin/bash cd /Pictures cp -av *jpg /TINYUSB 2> /tmp/report
That's better, but it doesn't have the "-v" output. Isn't there a way to get both?
Yes, there is, although it does involve a little more work. The script that follow does that and a few other checks.
#!/bin/bash
# these lines just make sure we are in the right place
cd /Pictures || echo "`date` Copy script can't find /Pictures!!" | lp
cd /Pictures || exit 1
ls *.jpg > /tmp/report
# if there is nothing to copy, /tmp/report will say so
# if there are files, /tmp/report is nulled out and will be empty
# make sure TINYUSB is mounted
/bin/mount | grep TINYUSB || echo "TINYUSB not mounted!" | lp
/bin/mount | grep TINYUSB || exit 1
for i in *.jpg
do
cp -av "$i" /TINYUSB > /tmp/failed 2>&1
# /tmp/failed will have both -v and error output
# but we'll only copy it if there really was an error
case $? in
0) : ;;
*) echo "Exit code was $?" >> /tmp/failed;
echo " " >> /tmp/failed;
echo "`date` Copy of $i failed" > /tmp/message;
cat /tmp/message /tmp/failed >> /tmp/report;;
esac
grep -q "No space left on device" /tmp/report && lp /tmp/report
grep -q "No space left on device" /tmp/report && exit 1
# no reason to go on if there is no space
done
test -s /tmp/report && lp /tmp/report
# if no errors. nothing will print because /tmp/report will still be empty
The "$?" in the case switch will be the exit code of the last cp command. If all went well, it will be 0 and we do nothing. If it's not 0, we'll add /tmp/failed to /tmp/report.
If the device has run out of space, there is no reason to keep trying, so we'll quit the script then and there.
There's no need to do that "cd /Pictures" or the "grep -q" twice.
grep -q "No space left on device" /tmp/report && { lp /tmp/report ;exit 1; }
Spaces after "{" and before "}" are necessary and that ";" after "exit 1" is also needed.
However, doing it twice makes it very obvious what you want to happen and why and saves you from forgetting the spaces or the semicolon.
There are probably other things that can go wrong that I haven't thought of today. If you know one, let me know and we'll add it.
More Articles by Anthony Lawrence - Find me on Google+
Have you tried Searching this site?
Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.
Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.
Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.
We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.
Click here to add your comments
Don't miss responses! Subscribe to Comments by RSS or by Email
Click here to add your comments
If you want a picture to show with your comment, go get a Gravatar