Capture and report (Bash Scripting)

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.



Got something to add? Send me email.





(OLDER) <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> -> Capture and report (Bash Scripting):Bash|Scripting|Basics::/Basics/capture_report.html




Increase ad revenue 50-250% with Ezoic


More Articles by

Find me on Google+

© Anthony Lawrence



Kerio Samepage


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.

Contact us





Whenever the literary German dives into a sentence, that is the last you are going to see of him till he emerges on the other side of his Atlantic with his verb in his mouth. (Mark Twain)

FORTRAN's tragic fate has been its wide acceptance, mentally chaining thousands and thousands of programmers to our past mistakes. (Edsger W. Dijkstra)








This post tagged: