2

I need to store stderr (2>&1) int a variable and then echo it.

find $var -type f -exec file -b {} \; | sort 2>&1 | uniq -c

Sometimes, when $var is /etc it writes error with permission, so I need to check if 2>&1 is error, or not.

I can't use temp files

fedorqui
  • 275,237
  • 103
  • 548
  • 598
Brky
  • 59
  • 11
  • Not sure whose stderr you want to redirect and where you want to echo it, but [this](http://stackoverflow.com/a/28796214/6770384) may help you. – Socowi Mar 27 '17 at 10:05

1 Answers1

1

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.

Mario
  • 679
  • 6
  • 10