簡體   English   中英

Bash:暫停並繼續執行空格鍵

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM