[英]Bash: pause and continue execution with spacebar
我運行的代碼在一個多小時內產生大量輸出。 在執行期間,我使用tee
輸出記錄到文件中。 然而,仍然發送到我的終端的大量輸出有點麻煩,所以我做了一個小函數ShowLastLines
,我可以管道輸出,這將只顯示最后15行的輸出和實時更新。
這是腳本:
function ShowLastLines {
numberoflines=15
i=1
while read var
do
echo $var
if [ $i -gt $numberoflines ]
then
tput sc && tput cuu $(( $numberoflines +1 )) && tput dl 1 && tput rc && tput cuu 1
fi
(( i++ ))
done
}
在實踐中我像這樣使用它:
( long code ) 2>&1 | tee output.log | ShowLastLines
這可以很好地按預期工作,但是我想添加一個功能,即當我點擊空格鍵時我想暫停輸出(在ShowLastLines
,當然不是在原始執行中)(例如,調查我注意到的一些細節),當我再次點擊空格鍵時它會繼續(它會趕上執行輸出)。
我試了幾件事,但到目前為止還沒有成功。 我相信可能通過使用stty
將標准輸入置於非阻塞模式(如在此線程中 ):
stty -echo -icanon time 0 min 0
但我無法將其與現有的read
相結合。
一個重要的側面評論:我在一個AFS集群上,因此我無法訪問日志文件(由tee
編寫),直到計算結束,因為不同機器之間的同步是如何實現的(我知道否則它會更容易在日志文件中使用tail -f
)。
Ps:最有用的實現是,當通過按空格鍵暫停輸出時,可以在輸出中向上滾動以顯示之前的行。 任何建議都是受歡迎的,但我意識到這可能需要一個完全不同的實現,可能會增加大量的計算開銷,所以我很高興有一個解決方案,通過空格鍵簡單地暫停。
這可能最好用實際程序使用select()
來同時讀取管道和用戶的輸入。
但是,在Bash腳本中,您可以使用帶有小超時的read
來檢查用戶是否已按下某個鍵:
buf() {
stty -echo < /dev/tty
while read line ; do
echo "$line"
if read -n1 -t0.0001 -u3 3</dev/tty ; then
echo paused.
read -n1 -u3 3</dev/tty
fi
done
stty echo < /dev/tty
}
read -n1
不會等待整行,但會在收到一個字符后立即返回。 我們需要從/dev/tty
read
(stderr也可以這樣做),因為我們期望來自stdin的管道輸入,如somecmd | buf
somecmd | buf
。
這里的缺點是如果你停止輸出太長時間,管道將停止並停止產生輸出的過程。 您可以通過在管道中使用pv
(例如, ...| pv -qB 64k |...
)來充當緩沖區。 雖然查看讀取端暫停時發送的輸出有點困難。
如評論中所述,您也可以使用終端模擬器的緩沖來執行此操作。 這將具有相同的缺點,即停止輸出太長時間將再次停止管道的寫入側。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.