非标准的io重定向

时间:2013-07-25 21:20:54

标签: bash stdout stderr io-redirection

如何将脚本的stdout和stderr重定向到文件,同时还将脚本的stderr发送到stdout。

举例说明:

testscript:

#!/bin/bash
echo "this goes to stdout"
echo "this goes to stderr" >&2

以这样的方式执行testscript,将其打印到控制台:

this goes to stderr

,这将转到日志文件:

this goes to stdout
this goes to stderr

我觉得我接近使用fifo,但从未到过那里。需要的是stderr的tee。想法?

4 个答案:

答案 0 :(得分:0)

我想现在对于那些正在处理答案的人来说这不公平,但我想我明白了:

if [ ! -e /tmp/deployed.err ]
then
  mkfifo /tmp/deployed.err
fi

tee -a testlog </tmp/deployed.err &

./testscript 2>/tmp/deployed.err 1>>testlog

它似乎有效,但我担心日志中的消息会出现故障。任何人都有更好的主意吗?

答案 1 :(得分:0)

command 2>&1 | tee somefile

会将stderr和stdout一起发送到tee所以,这两个文件都会转到文件和stdout。

如果您想将stderr和标准输出重定向到其他tee,您可以使用以下内容:

command > >(tee out.log) 2> >(tee err.log >&2)

依此类推......(> >(之间的空格是强制性的)

答案 2 :(得分:0)

您可以尝试这样的事情

./script 2>&1 1>log | tee -a log

stdout发送到登录1>log,tee完成将其发送到stdout并登录的工作。

PS:不知怎的,我对这种方法感觉不好。如果你愿意,请评论。

答案 3 :(得分:0)

simething简化。这是基于bashizm内部fork 首先,测试脚本:

#!/bin/bash
for i in {1..1000}; do
    echo STDOUT $i>&1
    echo STDERR $i>&2
done

然后,重定向脚本:

(./xxtext.sh 1>>logfile)2>&1|\ #subprocess/fork in brackets with redir stdout to logfile.
#above, main process redirect stderr to stdout for properly pipe
while read x; do echo $x; echo $x>>logfile; done #second read sequently stdin
#redirected from stderr, and both print to the screen and append to logfile.

不幸的是,这不能正确保存序列,因为两个流由两个不同的进程管理,并使用管道缓冲。

如果你真的想要保存序列,唯一的方法就是使用'select'系统调用,并从内部打开的脚本中读取stdout和stderr。我相信bash不支持这个。 您可以使用C或Perl或其他更高级的语言执行此操作。 perl中的有用示例我在http://www.perlmonks.org/bare/?node_id=419919找到 这称为'bc'命令。