
我有一個 bash shell 腳本,其中我透過大約 5 或 6 個不同的程式傳輸一些數據,然後將最終結果放入製表符分隔的檔案中。
然後,我對一個單獨的相似資料集再次執行相同的操作,並將其輸出到第二個檔案。
然後將這兩個檔案輸入到另一個程式中進行比較分析。例如簡化
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv
我的問題是:如何讓步驟 1 和步驟 2 同時運行(例如使用 &),但僅在兩者完成時啟動步驟 3(AnalysisProg)?
謝謝
ps AnalysisProg 不適用於流或 fifo。
答案1
使用wait
。例如:
Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg
將要:
- 將 Data1 和 Data2 管線作為背景作業來執行
- 等他們倆完成
- 運行 AnalysisProg。
參見,例如,這個問題。
答案2
如果你只有 2 個文件,cxw 的答案無疑是更好的解決方案。如果這 2 個文件只是範例,而您實際上有 10000 個文件,那麼「&」解決方案將不起作用,因為這會使您的伺服器超載。為此,您需要像 GNU Parallel 這樣的工具:
ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv
要了解有關 GNU Parallel 的更多資訊:
- 觀看介紹影片以進行快速介紹: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
- 瀏覽本教學 (man parallel_tutorial)。你的命令列會喜歡你的。
答案3
執行此操作的一種方法可能類似於:
AnalysisProg <<PREPROCESS /dev/stdin
$(
{ process1=$( pipe | line | 1 >&2 & echo $! )
process2=$( pipe | line | 2 >&2 & echo $! )
while ps -p $process1 $process2 >/dev/null; do
sleep 1
done
} 2>&1
)
#END
PREPROCESS
透過這種方式,您可以將兩個管道設定為後台,但仍等待它們完成執行,然後再將它們的輸出合併到標準輸入中,該標準輸入在此處文件中進行評估並交給 AnalysisProg。如果你可以使用wait
這甚至比while ps
循環,但是,取決於外殼,wait
如果您指示它等待某個進程,則可以反對不是目前 shell 的子級。
另請注意,上述方法將整理輸出 - 因此兩個進程將同時寫出。如果您希望將它們分開,或者將它們附加到另一個上,您可以這樣做:
AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)
答案4
嘗試使用這個。
rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
if [ $? -ne 0 ]
then
AnalysisProg -i Data1res.csv Data2res.csv
exit 0
fi
done