在STDERR之前显示STDOUT?


9

我是bash的新手,我一生都./fff无法解决如何在stderr之前运行某个命令,假设并打印常规stdouts(我对自己的含义感到困惑)

例如

$ printf "I am a\ndrill\n" > fff; 
$ cat fff nofile fff nofile fff

I am a
drill
cat: nofile: No such file or directory
I am a
drill
cat: nofile: No such file or directory
I am a
drill

需要打印如下:

I am a
drill
I am a
drill
I am a
drill
cat: nofile: No such file or directory
cat: nofile: No such file or directory

我知道我需要先将输出重定向到文件,然后将错误附加到同一文件,但这是我得到的输出

$ cat ./foo nofile ./foo nofile ./foo <<< $(touch fin) > see 2>> see 

I am a
drill
I am a
drill
I am a
drill
ectory
cat: nofile: No such file or directory

2
难道cat真的将“A”的“一些”?
德米特里·格里戈里耶夫

哦,当我可能弄乱了琴弦。我将立即对其进行编辑@DmitryGrigoryev
MeOw

Answers:


18

无论如何,您都需要将stderr输出保存在某个地方,以便最终显示它。

我想到一个文件

fff 2> file; cat file >&2

内存(此处使用spongefrom moreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1{...}文件描述符(fd)中的3指向与原始 stdout 相同的资源(因此我们可以使用它来还原的stdout fff)。
  • fff <redirs> | sponge <redirs>fffsponge同时启动(<redirs>独立应用),其中fff的stdout进入管道,而spongestdin为管道的另一端。
  • 2>&1fff(stderr)的fd 2 指向与1:管道相同的东西,因此fff,错误sponge通过该管道进入。
  • >&3:现在stdout指向原始stdout(重定向回原来的状态)
  • 3>&-:我们关闭fff不需要的fd 2
  • sponge累积其输入并仅>&2在它在其stdin上检测到eof后(假设是何时fff终止并且已经将所有输出写入其stdout上)显示(在已重定向到与stderr相同资源的stdout上)。

如果sponge未安装,则可以将其替换为perl -0777 -pe ''。使用-pe ''perl可一次从其输入读取一条记录并将其写入stdout。-0777是slurp模式,其中(在这种情况下只有一个)记录是整个输入。


如果有时间,请把它分解!
乔治·乌德森

我们可以tee代替sponge...吗?
乔治·瓦西里乌

@GeorgeUdosen参见编辑。
斯特凡Chazelas

1
@GeorgeVasiliou,tee不保存数据,而是在读取数据后立即将其写入。
斯特凡Chazelas

2
@MeOw:很好,但是,正如Stéphane答案的第三行所示,您无需保存标准输出;随便吧cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt。(你可能并不想要使用>>。)另外,斯特凡使良好的出发点,你可能应该做cat ferr.txt >&2写入标准错误信息标准错误。
G-Man说'Resstate Monica''18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.