Ssh
獲取 ssh 轉發信號
我希望能夠通過 ssh 發送信號(SIGINT 是最重要的)。
這個命令:
ssh server "sleep 1000;echo f" > foo
將在伺服器上開始睡眠,並在 1000 秒後將 ‘f\n’ 放入我本地電腦上的文件 foo 中。如果我按 CTRL-C(即向 ssh 發送 SIGINT),它將終止 ssh,但不會終止遠端伺服器上的睡眠。我希望它殺死遠端伺服器上的睡眠。
所以我嘗試了:
ssh server -t "sleep 1000;echo f" > foo
但是,如果 stdin 不是終端,我會收到此錯誤:
Pseudo-terminal will not be allocated because stdin is not a terminal.
然後 SIGINT 仍然沒有轉發。
所以我嘗試了:
ssh server -t -t "sleep 1000;echo f" > output
但是 foo 中的輸出不是 ‘f\n’ 而是 ‘f\r\n’ 這在我的情況下是災難性的(因為我的輸出是二進制數據)。
在上面我使用“sleep 1000;echo f”,但實際上它是由使用者提供的,因此它可以包含任何內容。但是,如果我們可以讓它適用於“sleep 1000;echo f”,我們很可能讓它適用於所有現實情況。
我真的不關心在另一端獲得一個偽終端,但我一直無法找到任何其他方式讓 ssh 轉發我的 SIGINT。
還有其他方法嗎?
編輯:
使用者可以給出從標準輸入讀取二進制數據的命令,例如:
seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo
使用者可以給出 CPU 密集型命令,例如:
ssh server "timeout 1000 burnP6"
編輯2:
似乎對我有用的版本是:
your_preprocessing | uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - | your_command | uuencode a" | uudecode -o - | your_postprocessing
感謝 digital_infinity 為我指明了正確的方向。
簡短的回答:
ssh -t fs "stty isig intr ^N -echoctl ; trap '/bin/true' SIGINT; sleep 1000; echo f" > foo
並按 CTRL+N 停止程序。
長解釋:
- 您必須使用
stty
選項intr
來更改您的伺服器或本地中斷字元以不相互衝突。在上面的命令中,我將伺服器中斷字元更改為 CTRL+N。您可以更改本地中斷字元並保留伺服器的中斷字元而不做任何更改。- 如果您不希望中斷字元出現在您的輸出(和任何其他控製字元)中,請使用
stty -echoctl
.- 您必須確保在 sshd 呼叫的伺服器 bash 上打開了控製字元。如果你不這樣做,你最終可能會在註銷後程序仍然掛起。
stty isig
- 你實際上用空語句擷取
SIGINT
信號。trap '/bin/true' SIGINT
如果沒有陷阱,您將不會在 SIGINT 信號結束後獲得任何標準輸出。