Grégoire Cachet
Grégoire Cachet

Reputation: 2597

How to redirect all stderr in bash?

I'm looking for a way to redirect all the stderr streams in interactive bash (ideally to its calling parent process).

I don't want to redirect stderr stream from each individual command, which I could do by appending 2> a_file to each command.

By default, these stderr streams are redirected to the stdout of an interactive bash. I would like to get them on the stderr of this interactive bash process in order to prevent my stdout to be polluted by error messages and be able to treat them separatly.

Any ideas?

I still haven't found an answer ... But maybe it's actually a tty parameter. Does anybody knows something about tty/interactive shell responsibility for handling stderr ?

Upvotes: 10

Views: 21823

Answers (7)

stefano
stefano

Reputation: 4053

I find a good way is to surround the commands by parentheses, '()', (launch a sub-shell) or curly-braces, '{}' (no sub-shell; faster):

{
  cmd1
  cmd2
  ...
  cmdN
} 2> error.log

Of course, this can be done on 1 line:

{ cmd1; cmd2; ... cmdN; } 2> error.log

Upvotes: 3

Kit Gerrits
Kit Gerrits

Reputation: 21

Two things:

  1. Using 2>&1 in a remote ssh command results in the error ending up inside the local tarfile, resulting in a 'broken' backup.
  2. If you want to apply a redirect on the other side of the ssh, remember to escape the redirect command.

My suggestion would be to redirect stderr on the remote side to a file and pick it up later, in case of an error.

example:

ssh -t remotehost tar -cf - /mnt/backup 2\>backup.err > localbackup.tar
EXITSTATUS=$?
if [ $EXITSTATUS != "0" ] then 
  echo Error occurred!
  ssh remotehost cat backup.err >localbackup.errors
  cat localbackup.errors
  ssh remotehost rm backup.err 
else 
  echo Backup completed successfully!
  ssh remotehost rm backup.err 
fi

Upvotes: 2

crb
crb

Reputation: 8178

Tried ssh -t to create a pseudo-TTY at the remote end?

Upvotes: 0

Gunstick
Gunstick

Reputation: 431

I don't see your problem it works as designed:

$ ssh remotehost 'ls nosuchfile; ls /etc/passwd' >/tmp/stdout 2>/tmp/stderr 
$ cat /tmp/stdout  
/etc/passwd 
$ cat /tmp/stderr 
nosuchfile not found

Upvotes: 2

jtimberman
jtimberman

Reputation: 8258

Try your commands in doublequotes, like so:

ssh remotehost "command" 2>~/stderr

Tested on my local system using a nonexistant file on the remote host.

$ ssh remotehost "tail x;head x" 2>~/stderr
$ cat stderr 
tail: cannot open `x' for reading: No such file or directory
head: cannot open `x' for reading: No such file or directory

Upvotes: 2

gavrie
gavrie

Reputation: 1821

Use the exec builtin in bash:

exec 2> /tmp/myfile

Upvotes: 10

caerwyn
caerwyn

Reputation: 306

You could launch a new bash process redirecting the stderr of that process:

  $ bash -i 2> stderr.log
  $ 

Upvotes: 4

Related Questions