在 STDERR 之前显示 STDOUT?

在 STDERR 之前显示 STDOUT?

我是 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

答案1

你需要抓住无论如何,stderr 输出都能够在最后显示它。

A文件我想到:

fff 2> file; cat file >&2

或者记忆(这里使用spongefrom moreutils):

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

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

相关内容