Gar*_*ett 2 perl stderr stdin stdout
我正在运行以下命令:
[user@server ~]$ /usr/sbin/ntpdate -d IPREMOVEDFORSECURITY | egrep 'transmit timestamp' | tail -1 | awk '{print $4, $5, $6, $7, $8}'
host found : HOSTREMOVEDFORSECURITY
Tue, Feb 15 2011 12:38:38.321
Run Code Online (Sandbox Code Playgroud)
所以问题是,无论我使用哪种类型的重定向,我总是得到“找到主机:”行。我尝试了以下方法:
0>/dev/null
1>/dev/null
2>/dev/null
2>&1
2>&/dev/null
Run Code Online (Sandbox Code Playgroud)
以及我能想到的或能够在网上找到的所有其他变体。我需要并希望返回的是该命令输出的第二行(时间戳)。我不明白为什么我似乎无法影响“主机找到:”行?!?!
我通过 perl 运行这些命令,但是在 bash 中直接运行它们时我看到了相同的行为。我需要抑制该 host: 行,因为在 perl 中,我使用反引号运行命令将输出分配给变量,并根据其他一些条件输出干净的响应。无论如何,该主机行显示并混淆了我的脚本输出,尽管它不会影响实际分配给变量的内容。
我的假设是这条线没有使用普通的 STDIN、STDOUT、STDERR 线程,但我似乎无法确定关于第 4 种输出方法的任何特定信息。我发现的每个网站都只谈论这三个。
如果有人对此有答案,请告诉我!
PS:这不是显示此行为的唯一命令,chkconfig 和其他一些命令也执行此操作,我真的很想弄清楚如何抑制这种不必要的输出。
ntpdate 正在将“找到的主机”打印到标准错误,并将其他所有内容打印到标准输出。这会将所有内容重定向到标准输出:
/usr/sbin/ntpdate -d localhost 2>&1 | egrep 'transmit timestamp' 2>/dev/null | \
tail -1 | awk '{print $4, $5, $6, $7, $8}'
Run Code Online (Sandbox Code Playgroud)
然后 egrep 删除 'host found' 行,因为它不匹配。
我认为您的困惑可能来自将重定向放在管道的末尾而不是管道内。在执行管道的其余部分之前,您必须找到将额外数据打印到 stderr(在本例中为 ntpdate)的命令,并在此时重定向或抑制 stderr 。