立即停止在 SSH 會話中執行的程式的輸出

立即停止在 SSH 會話中執行的程式的輸出

問題

我執行透過 SSH 輸出大量資訊的命令。例如,我愚蠢地在執行一百萬次的循環中添加調試信息,或者只是cat /dev/urandom為了好玩而運行。

終端機裡充斥著資訊。

舉例說明我正在談論的內容

我想盡快終止命令並修復我的程式。我不在乎它打印什麼。現在,問題是我按Ctrl+C ASAP(在上面的範例中,我在運行命令後立即按下了它),但是列印所有我不需要的資訊仍然需要時間

我嘗試過的

我嘗試按Ctrl+C如此用力,以至於當終端最終趕上時,它產生了有趣的結果:

OUTPUT HERE^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
^C^C

^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C

我還讀到了Ctrl+S顯然用於告訴終端“停止輸出,我需要趕上”但顯然它什麼也沒做。

雜項細節

我不想改變我運行的命令,這樣我就可以在任何情況下拯救自己,即使我不記得我運行的程式可能會這樣結束。

我的 SSH 用戶端在 MinTTY 中的 Cygwin ( CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwin) 上運行,終端類型設定為xterm-256color

SSH 伺服器在 Debian ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux) 上運作。

答案1

我通常將輸出運行到,less以便我可以透過less使用q密鑰來殺死它。

$ cmd | less

例子

$ cat /dev/urandom | less

   SS #2

點擊q+後Enter,它將退出並返回到正常的終端,使其保持乾淨整潔。

為什麼會發生這種情況?

您遇到的問題是有一些緩衝區(用於 STDOUT)與顯示器的輸出一起排隊。這些緩衝區被填滿的速度如此之快,以至於您無法足夠快地中斷它以停止它。

                                    SS #1

要停用/限制此效果,您可以停用 STDOUT 緩衝,這應該會使使用的回應速度更快stdbuf,但您可能必須使用這些設定才能按照您想要的方式獲得結果。若要取消緩衝​​ STDOUT,您可以使用以下命令:

$ stdbuf -o0 <cmd>

手冊頁stdbuf詳細介紹了您可以使用的選項:

    If MODE is 'L' the corresponding stream will be line buffered.  This 
    option is invalid with standard input.

    If MODE is '0' the corresponding stream will be unbuffered.

    Otherwise MODE is a number which may be followed by one of the 
    following: KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so
    on for G, T, P, E, Z, Y.  In this case the corresponding stream will be 
    fully buffered with the  buffer  size  set  to  MODE
    bytes.

要了解緩衝如何運作的良好背景,我強烈建議您查看這篇 Pixel Beat 的文章,標題為:標準流中的緩衝。它甚至包括漂亮的圖片。

參考

答案2

其中一些輸出將被緩衝。您將Ctrl+發送C到遠端,這會中斷正在執行的程式。該程式存在,並且 shell 發送字元以再次向您顯示提示符。在顯示提示之前,您的螢幕將首先顯示所有已緩衝且已傳送給您的資料。

您要求的是程式停止並且傳輸中的資料以某種方式消失。這是不可能發生的,因為它已經在路上了。

確保看不到此數據的唯一方法是退出終端,然後重新連接到遙控器 - 但這可能比等待緩衝數據顯示要費力得多。

答案3

有多個級別的緩衝。當您按Ctrl+時C,程式將停止向終端發送資料。這不會影響終端模擬器尚未顯示的資料。

當您以非常高的速度顯示資料時,終端無法跟上並且會出現延遲。這就是這裡發生的事情:顯示文字比產生這些隨機數字要昂貴得多。是的,即使使用點陣字體 - 相比之下,產生加密品質的隨機數也非常便宜。 (我剛剛在我的機器上嘗試過,X 進程使 CPU 飽和,xterm佔用了幾個 %,cat(隨機數生成所考慮的)勉強達到 1%。而且這是使用點陣圖字體時的情況。)

如果您希望現在停止,請終止終端模擬器。如果您不想這樣做,至少最小化視窗;智慧型終端模擬器(例如xterm)不會映射窗口,這節省了X CPU時間,因此垃圾會更快完成顯示。 X 伺服器具有高優先級,因此當 xterm 在背景處理資料時,這將對電腦的回應能力產生很大影響。

當這一切都在遠端 shell 中進行時,延遲會更嚴重,因為產生的資料cat必須先透過 SSH 連線。你按Ctrl+C也必須透過 SSH 連線;它獲得了更高的優先順序(它被發送到帶外),但這仍然需要一些時間,在此期間累積更多的輸出。除了關閉 SSH 連線(可以按下Enterthen 來完成~.)之外,無法抑制傳輸中的資料。

答案4

我遇到了同樣的問題,並且對這裡的答案不滿意,因此我進行了更深入的研究。其他人已經提到您的命令輸出資料的速度比您的 ssh 可以接受的速度快,因此資料緩衝區和緩衝區無法停止。

要解決此問題,請透過將命令輸出限制為 ssh 會話可以採用的最大速率來避免緩衝,已經存在可以執行此操作的命令。

設定時,先找出您的會話最大速率:

# Get transfer <TIME> of a large file (>10MB preferable)
/usr/bin/time -f "%e" cat <FILENAME>

# Get file <SIZE> in bytes
stat --printf="%s\n" <FILENAME>

# Calculate <RATE>
echo "<SIZE> / <TIME>" | bc

最後,相應地限制你的實際命令。

<YOUR_COMMAND> | pv -qL <RATE>

例子:

/usr/bin/time -f "%e" cat large_reference_file.txt
31.26

stat --printf="%s\n" cat large_reference_file.txt
17302734

echo "17302734 / 31.26" | bc
553510

# Throttle my command to 553510B/s
cat some_other_file.txt | pv -qL 553510

您可能需要稍微降低速率,以防您的連線速度不時下降一點。如果它下降,行為將返回問題,即無回應的 ctrl-c。

可選的節流貓別名:

# bash
alias tcat='tcat(){ cat $@ | pv -qL 400k ; }; tcat'

# tcsh
alias tcat 'cat \!* | pv -qL 400k'

# usage: tcat <FILENAME>

現在 ctrl-c 按預期工作,立即終止輸出,因為緩衝的內容很少(如果有的話)。

相關內容