Bash

在 STDERR 之前顯示 STDOUT?

  • January 13, 2022

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

需要列印如下:

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

無論如何,您都需要stderr 輸出保存在某個地方才能在最後顯示它。

想到一個文件:

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: fd 2 of fff(stderr) 指向與 1: 相同的東西:此時的管道,因此fff錯誤sponge通過該管道進入。
  • >&3:現在標準輸出指向原始標準輸出(重定向回原來的樣子)
  • 3>&-``fff: 我們關閉不需要的 fd 3
  • sponge累積其輸入並僅在其標準輸入上檢測到 eof 後才顯示(在其已被重定向>&2到與 stderr 相同的資源的標準輸出上)(假設是當fff終止並已將其所有輸出寫入其標準輸出時)。

如果sponge未安裝,您可以將其替換為perl -0777 -pe ''. 使用-pe '',perl從其輸入中一次讀取一條記錄並將其寫入標準輸出。-0777是 slurp 模式,其中(在這種情況下只有一個)記錄是整個輸入。

引用自:https://unix.stackexchange.com/questions/417124