Standard Errorcode needs to be catched after execution, so working with pipes |
isnt doable in your case.
for example...
#!/bin/bash
FAKEDIR="/this/dir/dont/exist"
#example one
ERRMSG=$(mkdir "$FAKEDIR" 2>&1)
ERRNO="$?" # determine Error Code
if [ "$ERRNO" -ne 0 ]; then # If variable is Not Equal 0
echo "Error: ${ERRNO} Message: ${ERRMSG}"
fi
#example two
find -type f -exec "$FAKEDIR" -b "{} \;" | sort | uniq -c
ERRNO="$?" # this is the error code of uniq only
if [ "$ERRNO" -ne 0 ]; then
echo "Ths text will never be shown, even 'find' went wrong."
fi
# example three
FIND=$(find "$FAKEDIR" -type f -exec file -b "{} \;" 2>&1)
ERRNO="$?" # determine Error Code
if [ "$ERRNO" -ne 0 ]; then
echo "Error: ${ERRNO} Message: ${FIND}"
else
echo "$FIND" | sort | uniq -c
ERRNO="$?"
if [ "$ERRNO" -ne 0 ]; then
echo "uniq returned an error code: ${ERRNO}"
fi
fi
exit "$ERRNO"
Two of the three examples catch the error code right after execution. this way you can pretty save run any script.
There are some advanced methods using exec
or trap
. but this will get to far for the beginning I think.
Addition:
To complete the post I would like explain how to use pipes
with error handling.
An error message comes over channel 2
only, so if you still want to use pipes you could dump all error messages to /dev/null
to be complete ignored, and you still can determine the return code via a trick called trap
. If any programm returns an error code different than 0 then the trap
will trigger. Otherwise error messages get processed by the tools behind the pipe.
example:
#!/bin/bash
trap "echo 'Error received. Exit programm!' && exit 0" ERR
mkdir "/this/dir/dont/exist"
echo "This text will never be shown!"
exit 0
The trap gets called when mkdir returns an error code, and this example works similar with pipes.
trap "commands..." ERR
programm args 2>/dev/null | programm args 2>/dev/null | ...
To make the code even smaller you could use exec
to reduce coding even more...
exec 2>/dev/null
trap "commands..." ERR
programm args | programm args | ...
Or you could use exec 2>&1
instead, if you still want to keep the messages. This is ok for some tests and you need to write less code, but its not recommend for most coding, keep this in mind.
You should also know its very importent when to declare stdin
, stdout
and stderr
. Every command uses channels in some way. So putting a 2>&1
somewhere in your code wont help you.