2016-11-12 72 views
1

我想要一個Bash腳本來生成一些輸出消息。該腳本應該捕獲消息,做一些過濾,轉換,然後將它們輸出到屏幕上。在本身內部過濾shell腳本輸出,腳本沒有終止

篩選結果在輸出中是正確的,但腳本未終止。我必須按回車鍵才能完成它。我如何解決它?

演示腳本:

#!/bin/bash 

exec &> >( 
     { 
     while read line; do 
      [ "$line" = "exit" ] && break 
      echo "`date +%H:%M:%S.%N` $line" 
     done 
     echo "while finish" 
     }) 

for ((i=3;i--;)); do 
    echo "text $i" 
done 

echo "exit" 
+0

我試圖改進描述。現在看起來......可以接受。但還是不太明白你的意思。 –

+0

http://stackoverflow.com/q/40564647/1030675 – choroba

回答

1

腳本終止,但腳本本身的後臺進程寫入任何輸出之前完成,所以首先顯示的提示,然後輸出,留下你的終端用空行看起來像腳本仍在運行。您可以鍵入任何命令而不是命令返回,並執行該命令。

爲了避免這種情況,您需要在顯式後臺作業中運行while循環,您可以在退出腳本之前等待。

mkfifo logpipe 
trap 'wait $logger_pid; rm logpipe' EXIT 

while read line; do 
    [ "$line" = "exit" ] && break 
    echo "$(date +%H:%M:%S.%N) $line" 
done < logpipe & 
logger_pid=$! 

exec &> logpipe 

# ========== 

for ((i=3;i--;)); do 
    echo "text $i" 
done 

echo "exit" 

while循環運行的背景下,從命名管道logpipe讀取它的輸入。一旦運行,您可以將所有輸出重定向到管道並啓動「主」腳本。退出陷阱確保您的腳本在while循環完成之前不會實際退出;它也爲您清理命名管道。


你可能沒有注意到的是,但不保證while環路將獲得其中的東西都寫他們的確切順序合併後的標準輸出和標準錯誤。例如,

echo out1 
echo err1 >&2 
echo out2 
echo err2 >&2 

最終可能會被解讀爲

out1 
err1 
err2 
out2 

每個流本身將保持在秩序,但兩人可能是任意合併。