【问题标题】:Duplicating stdout to stderr将标准输出复制到标准错误
【发布时间】:2011-03-09 16:14:32
【问题描述】:

我希望在 bash 下也将命令的标准输出复制到标准错误。比如:

$ echo "FooBar" (...)
FooBar
FooBar
$

其中 (...) 是重定向表达式。这可能吗?

【问题讨论】:

标签: bash redirect


【解决方案1】:

为了重定向到标准错误,我会使用>&2>/dev/stderr。对于复制输出,我会使用tee。它的缺点是需要一个临时文件:

echo "FooBar" | tee /tmp/stdout >&2 ; cat /tmp/stdout

【讨论】:

  • 错误。您有机会获得大流量并完全填充 /tmp 设备,通常连接到 /root 文件系统。
  • @Znik - /tmp/stdout 只是一个例子。随意用您的上下文中更合适的名称替换该文件名。
【解决方案2】:

将 tee 与 /dev/stderr 一起使用:

echo "FooBar" | tee /dev/stderr

或使用 awk/perl/python 手动进行复制:

echo "FooBar" | awk '{print;print > "/dev/stderr"}'

echo "FooBar" | perl -pe "print STDERR, $_;"

【讨论】:

  • perl 示例中 STDERR 后不需要的逗号
  • 哪个更易于跨操作系统和跨 Shell? tee /dev/stderrtee >(cat >&2) ?
  • 我打赌后者更兼容跨平台,因为 /dev/stderr 并非在每个发行版上都可用。
  • tee /dev/stderr 不适用于 systemd 服务,因为 fd 2 是套接字而不是 fifo。这记录在freedesktop.org/software/systemd/man/…
【解决方案3】:

使用进程替换:http://tldp.org/LDP/abs/html/process-sub.html

echo "FooBar" | tee >(cat >&2)

Tee 将文件名作为参数并将输出复制到该文件。通过进程替换,您可以使用进程而不是文件名>(cat),并且可以将此进程的输出重定向到 stderr >(cat >&2)

【讨论】:

  • 对于像 OS X 这样没有 /proc 文件系统的操作系统来说,这是一个很好的解决方案。
  • 这比依赖/dev/stderr要好,因为它可能不可写,如defdefred所示。
  • 在许多操作系统上,您甚至可能不需要使用cat。 (即echo "FooBar" | tee >(>&2)
【解决方案4】:
echo "FooBar" |tee /dev/stderr
tee: /dev/stderr: Permission denied

不适用于 RedHat 6.3

echo "FooBar" | ( read A ; echo $A ; echo $A >&2)

工作中

【讨论】:

  • 抱歉,已添加说明 ;-)
【解决方案5】:

如果我可以扩展@defdefred's answer,我正在使用多行

my_commmand | while read line; do echo $line; echo $line >&2; done

它的“优点”是不需要/调用tee 并使用内置函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 2019-09-03
    • 2012-05-26
    相关资源
    最近更新 更多