Shell sh:将stderr和stdout分别保存到,并且仍然打印它们

Shell sh:将stderr和stdout分别保存到,并且仍然打印它们,shell,sh,posix,stdout,stderr,Shell,Sh,Posix,Stdout,Stderr,我的脚本运行一些函数/外部程序。我需要正常打印它的输出。但是,我还需要将stdout和stderr分别保存到两个变量/文件中。让我们假设文件在shell中可能更容易 以下是我的脚本模板: #!/bin/sh print_things() { echo 'Some normal output' echo 'Now errors' 1>&2 echo 'Normal output again' echo 'And more errors' 1>&

我的脚本运行一些函数/外部程序。我需要正常打印它的输出。但是,我还需要将
stdout
stderr
分别保存到两个变量/文件中。让我们假设文件在shell中可能更容易

以下是我的脚本模板:

#!/bin/sh

print_things()
{
    echo 'Some normal output'
    echo 'Now errors' 1>&2
    echo 'Normal output again'
    echo 'And more errors' 1>&2
}

print_things | <do magic here>
<possibly a few more lines of magic>

# there will be the rest of the script

exit 0
执行“魔术”后,文件夹中应该有两个文件。一个包含整个
stdout
,另一个包含
stderr

保留退出状态而不将其保存到文件的额外点数


我正在寻找符合posix标准的解决方案。

这一问题已被多次询问和回答。唯一棘手的部分(或者说,不可能的部分)是分别路由这两个描述符,但仍然要确保它们是有序的。同样,我们在知识库中已经有了深入的答案,确切地描述了为什么当您的描述符不再是简单的
fdup()
s时,POSIX提供的订购担保不再适用……现在,您可以做的是保留一个系统调用级别的执行日志,并使用诸如
sysdig
这样的工具从日志中按照原始顺序重新构建输出,进行记录。如果不能在bash中完成,就不能在POSIX sh中完成(这不是伯恩——伯恩是20世纪70年代的壳牌,而POSIX sh是20世纪90年代早期的标准;自从太阳在2000年代中期停止了他们的产品以来,我还没有在外面见过伯恩壳牌)。而“这不可能”确实是答案。如果你有一个你认为适合bash的答案(并且满足了你所有的标准),将其翻译成POSIX sh将是儿戏。没有这样的答案,所以它的翻译无法完成……是的,GNU“Bourne”的名字,虽然很聪明,但有一点误导人们的历史。bash实际上是ksh而不是Bourne的近亲后裔(因此,早期ksh对POSIX sh标准产生了重大影响)例如,
$((1+1))
是ksh首创的,采用了POSIX sh标准,这是伯恩从未有过的。如果您想尝试使用
date
,您需要实际检索其输出,然后将其合并到一次写入中。也就是说,
echo“$(date+%s.%N)foobar”
在写入
foobar
的同时写入
date
的输出。但是,实际上,在分叉子shell以运行
date
时,会有几毫秒的延迟,收集其输出等,因此,您写入的时间戳将基于
date
最终结束的时间当它的输出被读取时,
wait()
等待它完成,而
echo
最终完成了它的写入。