[ Site Home | Journal Home ]
When I started bash scripting I typically wrote out the sequential code and ever hopeful, assumed that after a couple of tests that the code will always succeed. Such as in this example where it's assumed a file has been scp-ed therefore the local copy can now be deleted:
#do my important scp job scp user@host myfile #assume that SCP was OK, so delete local file rm myfile
A quick test or two might prove that the script is successful but in reality, whatever happens to scp, we delete the file anyway. In the eventuality that scp fails, we probably want to keep the file. Bash stores the return status of commands is stored in the $? variable. Usually the result value of 0 indicates success:
if [ "$?" -eq "0" ] ; then #sucesss(?) if [ "$?" -ne "0" ] #failed
Re-visiting the scp example,we can now check the return status
#do my important scp job scp user@host myfile if [ "$?" -ne "0" ] #failed echo "scp error - exiting" exit #should be ok to delete files rm #etc
The return value can be easily be printed/echo-ed:
jamespk@hal:~$ [ "abc" = "abc" ];echo $? 0 jamespk@hal:~$ [ "abc" = "xyz" ];echo $? 1 jamespk@hal:~$ test -d "$HOMEz" ;echo $? 1
Care needs to be taken when checking the return value, particular with pipes, as we see a value of 2 returned in the first example but when used with a pipe we get 0.
jamespk@hal:~$ ls does-not-exist ls: cannot access does-not-exist: No such file or directory jamespk@hal:~$ echo $? 2 jamespk@fuji:~$ ls does-not-exist | head ls: cannot access x: No such file or directory jamespk@fuji:~$ echo $? 0
This is where the $PIPESTATUS array comes in handy:
jamespk@fuji:~$ ls x | head ls: cannot access x: No such file or directory jamespk@fuji:~$ echo $PIPESTATUS 2 jamespk@fuji:~$ ls x | head ls: cannot access x: No such file or directory jamespk@fuji:~$ echo ${PIPESTATUS[@]} 2 0
posted at: 00:00 | path: /shell | permanent link to this entry