Pipe
當左命令產生大輸出時,如何在破折號中檢查左命令在管道“左|右”中的退出狀態
似乎變數“PIPESTATUS”在
dash
. 簡單的單獨執行不起作用,因為左側命令會產生非常大的輸出。我使用了一個fifo來完成這個任務:#!/bin/dash mkfifo command1 command2 dash -c "cat ./content;code=\${?};echo \${code} > command1 &" | dash -c "md5sum;code=\${?};echo \${code} > command2 &" echo "$(cat ./command1)" "$(cat ./command2)"
但我不知道為什麼它掛了?
您可以使用命名管道並手動連接兩個程序。以相反的順序啟動它們,因此左側在前台執行,您可以
$?
像往常一樣獲得其退出狀態。#!/bin/sh dir=$(mktemp -d) mkfifo "$dir/p" cat < "$dir/p" > /dev/null & ( echo foo; exit 12; ) > "$dir/p" echo "exit status: left: $?" rm -r "$dir"
或者如果你想要兩者,獲取後台程序的 PID
$!
並wait
獲取退出狀態。#!/bin/sh dir=$(mktemp -d) mkfifo "$dir/p" ( echo foo; exit 12; ) > "$dir/p" & # left-hand side pidleft=$! ( cat; exit 34; ) < "$dir/p" > /dev/null & # right-hand side pidright=$! wait "$pidleft"; exitleft=$? wait "$pidright"; exitright=$? echo "exit status: left: $exitleft right: $exitright" rm -r "$dir"
你仍然可以將管道的第二部分留在前景中,我只是想對稱地做。
例如,您還可以將退出狀態儲存到文件中,然後從那裡獲取它們:
#/bin/sh ( somecmd; echo "$?" > exit1 ) | ( cat; echo "$?" > exit2) echo "exit status: left: $(cat exit1) right: $(cat exit2)"
我認為命名管道在這裡用處不大,因為退出狀態只有幾個字節。
exit1
在嘗試讀取和exit2
第二行之前,shell 將等待管道完成。如果要改用命名管道,則需要將管道置於後台,因為對管道的寫入會阻塞,直到打開讀取端為止。
#/bin/sh mkfifo exit1 exit2 ( somecmd; echo "$?" > exit1 ) | ( cat; echo "$?" > exit2) & echo "exit status: left: $(cat exit1) right: $(cat exit2)"
但是,如果
cat
讀取管道的 s 由於某種原因沒有執行,則寫入它們的子shell 將在後台無限期地阻塞。