Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash Script Error Catching

I am very new to bash scripts, and for my first script attempt I am submitting files to my professor's dropbox within the same server.

The code is this:

#! /bin/bash
echo "Submit Lab$1? \c"

read choice

if [ $choice = "y" ]; then
   echo "Sending to Prof's dropbox..."
   cp -r /path/to/lab$1 /path/to/dropbox
else
   echo "Submission terminated."
fi

Usage for the command is simply "$ submit 1" (1 is a single integer, corresponding to which lab I want to submit)

The bash script appends the entered argument (a single integer) to the necessary filename (a directory), then submits that directory to my prof's dropbox using cp.

More for the sake of learning than of absolute necessity, I wanted to create a clean prompt that will catch any cp errors (such as file not existing), and be able to output my own error message.

So basically, something like:

echo "Submit lab$1?"

read choice

echo "Send to Prof's dropbox"
cp -rv /path/to/lab$1 /path/to/dropbox

<catch any errors from cp>

if [ cp has errors ]

   echo "Submission failed."

else if [ cp has no errors ]

   echo "Submission successful."

And so on...

I understand that I could use verbose mode, and that cp itself prints out errors, but as stated before, I'm doing this for the purpose of learning error catching in bash and being able to make a clean prompt.

Any help would be appreciated.

Thanks!


Also: I have a similar script which submits labs from my laptop, using scp. Assuming I have this question answered, can I apply the solutions to scp exactly the same way?

EDIT: I don't want cp errors to output to the shell! The most common error would probably be "cannot stat blah: no such file or directory." I would like to catch that error, and simply say "Submission failed."

EDIT #2: jcollado's answer is correct, the problem is on my part. Did not end the nested if-else with the proper "fi."

After fixing that up, it worked as intended. Still need to catch the error output but I believe I know where I need to go to figure that out on my own, so this question is answered as far as I'm concerned.

FINAL EDIT: Ah, what the heck - the redirect was so easy I figured I'd put the solution on here. If using Linux, simply add "2>/dev/null" (if you don't want error messages being saved in any file) after the cp to make "cp -r /first/path /second/path 2>/dev/null"

like image 222
skippr Avatar asked Jan 16 '12 20:01

skippr


People also ask

How do I see bash script errors?

In Bash scripting, $? prints the exit status. If it returns zero, it means there is no error. If it is non-zero, then you can conclude the earlier task has some issue.

Is there a try catch in bash?

The bash shell does not have any fancy exception swallowing mechanism like try/catch constructs.

How do I exit bash script error?

If you will invoke the script with source , you can use return <x> where <x> will be the script exit status (use a non-zero value for error or false).

What is set +E in bash?

set -e tells bash, in a script, to exit whenever anything returns a non-zero return value.


2 Answers

Although you can test $?, you can also test the exit status of a command directly:

if cp -rv /path/to/lab$1 /path/to/dropbox
then echo Submission successful
fi
exit $?

The errors were already reported to standard error by cp. The exit shown will exit with status 0 (success) if cp was successful; otherwise, it exits with the status that cp exited with.

Clearly, you can wrap that in a loop if you want to, or you can make it non-interactive (but any exit terminates the script).

like image 64
Jonathan Leffler Avatar answered Sep 28 '22 10:09

Jonathan Leffler


echo "Submit lab$1?"

read choice

echo "Send to Prof's dropbox"
cp -rv /path/to/lab$1 /path/to/dropbox &>/dev/null

[ $? -eq 0 ] && { #success, do something } || { #fail, do something }

And so on...

like image 21
chemila Avatar answered Sep 28 '22 11:09

chemila