MeO*_*eOw 9 shell bash io-redirection stdout stderr
我是 bash 新手,我一生都无法弄清楚如何运行某个命令,假设./fff并在 stderr 之前打印常规标准输出(我自己对含义感到困惑)
例如
$ 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
Run Code Online (Sandbox Code Playgroud)
需要打印如下:
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
Run Code Online (Sandbox Code Playgroud)
我知道我需要首先将我的输出重定向到一个文件,然后将错误附加到同一个文件中,但是这是我得到的输出
$ 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
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 18
无论如何,您都需要将 stderr 输出保存在某处才能在最后显示它。
想到一个文件:
fff 2> file; cat file >&2
Run Code Online (Sandbox Code Playgroud)
或内存(此处使用spongefrom moreutils):
{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
Run Code Online (Sandbox Code Playgroud)
{...} 3>&1: 在{...}文件描述符 (fd) 中 3 指向与原始标准输出相同的资源(因此我们可以使用它来恢复 的标准输出fff)。fff <redirs> | sponge <redirs>,fff并sponge同时开始(<redirs>独立应用),fff的 stdout 进入管道,而sponge的 stdin 是管道的另一端。2>&1: fd 2 of fff(stderr) 指向与 1: 相同的东西:此时的管道,因此fff错误sponge通过该管道。>&3:现在标准输出指向原始标准输出(重定向回原来的状态)3>&-: 我们关闭fff不需要的fd 2sponge累积其输入并仅>&2在其 stdin 上检测到 eof后才显示它(在其 stdout 上已重定向到与 stderr 相同的资源)(假设是在fff终止时并已将其所有输出写入其 stdout)。如果sponge未安装,您可以将其替换为perl -0777 -pe ''. 使用-pe '',perl从其输入中一次读取一条记录并将其写入标准输出。-0777是 slurp 模式,其中(在这种情况下只有一个)记录是整个输入。