Bash

多個光伏訂單

  • September 30, 2020

我在 Linux 機器上有一個腳本,其中一個花哨的 pv 通過管道連接到第二個 pv,該 pv 計算輸出行的子集。

這是腳本:

max=1000
for (( i=0; i<max; i++ )); do
 [[ $(shuf -i 1-100 -n 1) -lt 20 ]] && echo REMOVE || echo LEAVE
done | pv -F "%N %b / $(numfmt --to=si $max) %t %p %e" -c -N 'Lookups' -l -s $max \
 | grep --line-buffered '^REMOVE' \
 | pv -F "%N %b / $(numfmt --to=si $max)" -c -N 'Deletes' -l -s $max \
 >/dev/null
stty sane

我期望的是第一個 pv 總是首先顯示,第二個總是第二個。

像這個範例輸出:

$ ./fancy_pv.sh
 Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%            
 Deletes:  189  / 1.0K

但事實並非如此,有時他們交換位置,我看到這樣的事情:

$ ./fancy_pv.sh
 Deletes:  199  / 1.0K
 Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%            

有時我也會看到這樣的事情:

$ ./fancy_pv.sh
 Lookups:  321  / 1.0K 0:00:01 [===============================================================================================================>                                                                                                                                                                                                                                                 ] 32% ETA 0:00:02
 Deletes:  198  / 1.0K
 Lookups: 1.00k / 1.0K 0:00:03 [===============================================================================================================================================================================================================================================================================================================================================================>] 100%            

我知道這一定是因為 pv 刪除該行並重新繪製它的方式,但是我能做些什麼來防止它弄亂訂單嗎?

stty sane是否可以清理提示,因為有時 pv 會使終端無法使用。

謝謝

管道中的兩個pv程序可以按任意順序啟動。最新的輸出pv將在底線。

延遲pv你想要的底線。而不是pv …(其中表示所有參數)使用子shell:

( </dev/null sleep 1; exec pv … )

理論上,另一個pv可能仍然在延遲之後啟動,但在一個未完全過載的系統中,幾乎可以肯定延遲pv將最後啟動。

sleep無論如何都不應該從它的標準輸入中讀取;</dev/null以防萬一你sleep很奇怪。

我不確定某些競爭條件是否會導致出現額外的(陳舊的)行。如果是這樣,延遲一個pv也應該(幾乎肯定)有所幫助。在我的測試中,當終端需要“額外”更新時,輸出會被破壞。所以:

  • 不要在pvs 執行時調整終端的大小。

  • 避免滾動:

    • 在執行腳本之前,呼叫clear(或點擊Ctrl+ L)。這將清除螢幕,將提示放在頂部並在下方提供空間,而無需稍後滾動。
    • 不要在pvs 執行時輸入;尤其Enter應避免使用多個 s(最終可能會滾動文本)。
    • 一般來說,在 s 完成之前不要讓任何東西pv列印到終端pv。這適用於管道的其他部分(例如 via /dev/tty)、腳本中的非同步程序(例如簡單地通過它們的標準輸出)、腳本之外的程序(例如 via/dev/tty*/dev/pts/*)。

引用自:https://unix.stackexchange.com/questions/612213