3

我想将 SSH 调试信息与其他输入分开(并记录)。但是,如果我只是将 stderr 重定向到一个日志文件,我就有可能将来自 SSH 的输出和来自主机上的远程进程的输出结合起来(这可能会向 stderr 发送一些东西):

$ ssh -v somemachine 2> file.log

所以,我只想过滤掉那些匹配“debug1”的行:

$ ssh -v somemachine | awk '/debug1/ {print > "file.log"; next} {print}'

到目前为止很好,但是 ssh 的调试输出到 stderr。所以...

$ ssh -v somemachine 2>& | awk '/debug1/ {print > "file.log"; next} {print}'

又被坑了!我不想混合标准输出和标准错误。坏的!

像我这样的孩子是做什么的?我正要走命名管道或一些这样的狂野路线,但实际上,我需要知道的是如何让 awk 仅匹配来自 stderr 的模式。

4

3 回答 3

6

awk 实际上看不到来自 stderr 的输入 - 管道仅管道 stdout。为了做你想做的事,你将不得不搞砸重定向。如果您不关心标准输出上的内容,答案非常简单:

(ssh -v hostname somecommand > /dev/null) 2>&1 | awk '/debug1/ ...'

如果您关心标准输出上的内容,您将不得不做一些更复杂的事情。我相信这会奏效:

((ssh -v hostname somecommand 1>&3) 2>&1 | awk '/debug1/ ...' 1>&2) 3>&1

按顺序,这些重定向:

  • 将原始标准输出重定向到文件描述符 3
  • 将 stderr 重定向到 stdout 以供 awk 查看
  • 将标准输出重定向回标准错误(原来的位置)
  • 将文件描述符 3 重定向回标准输出(原来的位置)

PS 这个解决方案是 sh/bash 特定的。Jonathan Leffler 说它也应该与 ksh 一起使用。如果您使用的是不同的 shell,您可以尝试找到使用它执行相同重定向的语法 - 但如果不同的 shell 是 csh/tcsh,那么您可能只是搞砸了。众所周知,cshell 在处理 stdout/stderr 方面很糟糕。

于 2010-03-24T14:40:11.757 回答
0

试试这个(没有子shell):

{ ssh -v somemachine 2>&1 1>&3- | awk '/debug1/ {print > "file.log"; next} {print}'; } 3>&1

或者

{ ssh -v somemachine 2>&1 1>&3- | grep debug1 > file.log; } 3>&1

看到这个

于 2010-03-24T17:46:20.477 回答
0

非常感谢..!我将 ls 与 awk 一起使用,但无法重定向。

我用了:

FILES=`ls -lrt *.txt | awk '{print $9}' 2>> /dev/null`

现在:

FILES=`ls -lrt *.txt 2>> /dev/null | awk '{print $9}'`
于 2012-08-14T10:51:33.540 回答