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:

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.

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.

# 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
  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;;
  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
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?

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

privacy policy