我想逐行收集bash腳本中幾個子進程的輸出,以便將其轉發到另一個進程。後臺作業的亂碼輸出
我沒有發現任何東西可以保證子過程的輸出不會混合,但是對於我來說,每條輸出線都正確地輸出到輸出中是很重要的。輸出之間的順序並不重要。
這裏的混合/亂碼輸出的一個例子:
#!/bin/bash
for i in {1..1000}; do
({ echo BEGIN; dmesg; echo END; } | tr -d '\n'; echo) &
done
wait
運行此:
$ ./test_output.sh | perl -ne 'print "$1\n" if m/(.{1,20}BEGIN.{0,20})/' | head
0.000000] SRAT: PXMBEGIN[ 0.000000] Initi
ME through PCIe PME BEGIN[ 0.000000] Initi
ME through PCIe PME BEGIN[ 0.000000] Initi
[ 0.209816] pci 0BEGIN[ 0.000000] Initi
ciehp 0000:00:16.1:pBEGIN[ 0.000000] Initi
CI: Updating contextBEGIN[ 0.000000] Initi
l family 2[ 0.588BEGIN[ 0.000000] Initi
ME through PCIe PME BEGIN[ 0.000000] Initi
CI: Updating contextBEGIN[ 0.000000] Initi
3922 pages, LIFO batBEGIN[ 0.000000] Initi
你可以看到混合內容幾行。
當然,沒有&
一切都很好。
所以現在,我不得不將每個孩子的輸出重定向到一個文件,然後在所有這些文件之後再輸入一個大的wait
,cat
。
運行與GNU並行相同的任務是部分工作,但它不是我的環境中的一個選項。
GNU並行可以確保命令的輸出與 的輸出相同,只要您按順序運行命令即可。這使得 可能使用來自GNU並行的輸出作爲其他程序的輸入。
因此,GNU並行將在每個作業完成後立即寫入每個作業輸出,並且它會處理不混合輸出。那很好。但我也希望儘快獲得每項工作的輸出,即不要等待工作退出。有「-u」開關,但它會混合作業輸出。
我需要玩fifo,選擇,甚至寫一個perl腳本嗎?
-
我想我已經找到爲什麼/如何/時的輸出在男子7管
POSIX.1-2001弄混說,寫(2)的少於一PIPE_BUF字節必須爲 原子:輸出數據作爲連續的 序列寫入管道。超過PIPE_BUF字節的寫入可能是非原子的: 內核可能會將數據與其他進程寫入的數據交錯。 POSIX.1-2001要求PIPE_BUF至少爲512字節。 (在Linux上, PIPE_BUF是4096字節。)
是否重要的是你儘快得到任何輸出,或者如果你一旦完成所有事情都可以得到它,那很重要嗎? – Teddy 2013-05-12 16:27:39
我想盡快得到它,是的。否則,無論您將其存儲在內存還是每個進程的文件中,我都認爲這是相同的解決方案。 – 2013-05-12 16:49:51
您能詳細說明爲什麼10秒安裝的GNU並行(wget -O - pi.dk/3 | sh)不起作用?是否覆蓋:http://oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html – 2013-05-12 20:37:20