awk - 从 Awk 中读取 stderr

标签 awk redirect string-matching

我想将 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}'

又被打脸了!我不想混合 stdout 和 stderr。不好!<​​/p>

像我这样的 child 会做什么?我正打算走命名管道或类似的荒野路线,但实际上,我需要知道的是如何让 awk 仅匹配来自 stderr 的模式。

最佳答案

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 查看
  • 将 stdout 重定向回 stderr(它原来所在的位置)
  • 将文件描述符 3 重定向回标准输出(它原来所在的位置)

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

关于awk - 从 Awk 中读取 stderr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2508447/

相关文章:

awk 不打印整行

除 [ 和 ] 字符之外的空白分隔符的正则表达式

session - Spring 3 MVC session 在外部重定向后丢失

r - 模糊匹配电影标题,无需使用循环并按发行日期提取等效标题

正则表达式匹配具有特定属性的 html 标签

bash - 如何在unix shell脚本中查找文件中字符串的位置

linux - awk 命令输出到文本文件

.htaccess - 更改根文件夹目录并使用 .htaccess 重定向到 HTTPS

javascript - 重定向到另一个页面会阻止函数返回它们的值

string - 在每个给定输入文本中查找每个给定模式首次出现的算法