Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash: how to redirect stdin/stderr then later revert fd's?

I want a script to redirect stdin and stderr to a file, do a bunch of stuff, then undo those redirections and take action on the file contents. I'm trying:

function redirect(){
   exec 3>&1
   exec 4>&2
   exec 1>outfile 2>&1
}
function undirect(){
   exec 1>&3
   exec 2>&4
}
echo first
redirect
echo something
cat kjkk
undirect
if some_predicate outfile; then echo ERROR; fi

Which seems to do what I want, but it seems rather complex. Is there a cleaner/clearer way to do this?

like image 338
George Young Avatar asked Apr 27 '11 17:04

George Young


People also ask

Can stderr be redirected?

The regular output is sent to Standard Out (STDOUT) and the error messages are sent to Standard Error (STDERR). When you redirect console output using the > symbol, you are only redirecting STDOUT. In order to redirect STDERR, you have to specify 2> for the redirection symbol.

How do you redirect stdin stdout and stderr to a file?

Redirecting stdout and stderr to a file: The I/O streams can be redirected by putting the n> operator in use, where n is the file descriptor number. For redirecting stdout, we use “1>” and for stderr, “2>” is added as an operator.


2 Answers

If you really need to switch it back and forth, without knowing beforehand what will go where and when, that's pretty much the way to do it. Depending on your requirements though it might be neater to isolate the parts which need redirecting, and execute them as group, like so:

echo first
{
  echo something
  cat kjkk
} 1>outfile 2>&1
if some_predicate outfile; then echo ERROR; fi

the {} is called a group command, and the output from the entire group is redirected. If you prefer, you can do your execs in a subshell, as it only affects the subshell.

echo first
(
  exec 1>outfile 2>&1

  echo something
  cat kjkk
)
if some_predicate outfile; then echo ERROR; fi

Note that I'm using parentheses () here, rather than braces {} (which were used in the first example).

HTH

like image 92
falstro Avatar answered Nov 07 '22 13:11

falstro


It seems pretty clean to me. The only thing I'd to is to pass the "outfile" name as a parameter to the function, since you use the filename outside of the function

redirect() {
    exec 3>&1
    exec 4>&2
    exec 1>"$1" 2>&1
}
:
redirect outfile
:
if some_predicate outfile; ...
like image 31
glenn jackman Avatar answered Nov 07 '22 13:11

glenn jackman