In bash, how to redirect the stderr of a command inside the script to the stderr of the script itself?

Viewed 344

I have a bash script that has a print function, like this:

print(){
  [ $quiet == 1 ] && return
  type=$1; shift
  message="$*"; shift $#
  # shellcheck disable=SC2086
  if [ $type -eq 1 ]; then
    echo "$message"
  else
    >&2 echo "$message"
  fi
}

In a nutshell it receives 2 parameters, the first is the type, if 1 it will print the message on the screen (stdout), else (in that case 2) it will print the message on the stderr. Also, I have a quiet var that says that if my program is called with -q, it will not print anything on the screen whether its stdout or stderr (the function returns).

The problem is that throughout my program when I run commands, I run them more or less like below:

ip link add "${interface}" &&
  print 1 " interface ${interface} added successfuly." ||
  { print 2 "  interface ${interface} could not be added."; return 1; }

It works fine (success message is printed) if the command runs without error (meaning $? == 0) but if my quiet var is 1 and the command runs with error (meaning $? != 0) it will not print my message from the print() instruction (as expected), but it will print the error from the command itself, for example, RTNETLINK answers: File exists.

Ideally, what I wanted was to not just run all my commands with 2> /dev/null since the error messages can be important, but I would like to redirect them to my print() function with the type 2, so they would be printed on stderr only if my quiet var is 0. As if I ran a program with 2> $(print 2 "RTNETLINK answers: File exists") even though I know that this doesn't make since.

I thought about doing something like:

ip link add "${interface}" 2> /var/tmp/myprog.output || print 2 $(cat /var/tmp/myprog.output)

But 1) I would prefer not to use the filesystem for that and 2) there must be a more elegant way.

Any ideas?

1 Answers
Related