如何在Bash中重定向所有标准错误输出?

10

我正在寻找一种方法来重定向交互式bash中的所有stderr流(最好是到其调用父进程)。

我不想从每个单独的命令重定向stderr流,这可以通过在每个命令后添加2> a_file来实现。

默认情况下,这些stderr流会被重定向到交互式bash的stdout上。我希望将它们获取到此交互式bash进程的stderr上,以防止我的stdout受到错误消息的污染,并能够单独处理它们。

有什么想法吗?

我仍然没有找到答案...但也许这实际上是一个tty参数。有人知道关于tty/交互式shell处理stderr的责任的内容吗?


你在评论中提到了Python,能否展示一下你用来创建这些SSH流的代码?你没有使用popen/popen2/popen3吗? - jtimberman
7个回答

10
使用bash内置的exec命令: exec 2> /tmp/myfile,其中>表示重定向标准错误输出。

4
您可以启动一个新的bash进程,重定向该进程的stderr:
  $ bash -i 2> stderr.log
  $ 

3

我发现一个好的方法是用括号'()'(启动子shell)或花括号'{}'(不启动子shell,更快)来包围命令:

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

当然,这可以在一行上完成:

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

2

请将您的命令用双引号括起来,像这样:

ssh remotehost "command" 2>~/stderr

我在本地系统上测试了远程主机上不存在的文件。

$ 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

如果您在ssh之后直接输入命令,则不会在远程主机上加载shell。命令将直接通过ssh通道执行。我正在使用Python中的paramiko,但这是相同的。我的问题是我需要一个交互式shell来执行许多命令并仍然获取stderr。 - Grégoire Cachet

2

我看不到你的问题,它按设计工作:

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

2

两件事:

  1. 在远程ssh命令中使用2>&1会导致错误出现在本地tar文件中,从而导致备份“损坏”。
  2. 如果你想在ssh的另一侧应用重定向,请记得转义重定向命令。

我的建议是将远程端的stderr重定向到一个文件中,在出现错误时稍后再进行处理。

例如:

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

0
尝试使用ssh -t在远程端创建伪终端了吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接