次のコマンドを実行し、他のシステムで出力ファイルを監視しています。
ssh $ip_address 'for n in 1 2 3 4 5; do sleep 10; echo $n >>/tmp/count; done'
^C
ログインした端末を使用するか、単にシャットダウンしてsshコマンドを終了すると、リモートコマンドも終了することが予想されます。しかし、そのようなことは起こりません。/tmp/count
とにかく、1〜5のすべての数字を取得し、シェルとその子ps -ejH
プロセスがsleep
引き続き実行されているとマークされます。
これが予想される動作ですか?どこに文書化されていますか?無効にできますか?読んで、この動作をデフォルトの動作にするのではなく、nohupを使用して明示的に有効にする必要があると予想しました。
sshとsshdのマニュアルページを見ましたが、明確な内容が見つかりませんでした。
私は両方のシステムでrootログインとbashシェルを使用してRed Hat Enterprise Linux 6.2を実行しています。
答え1
ウーサーの答え端末を割り当てるように指示しますが、その理由は説明しません。その理由はsshだけに限られているのではなく、信号生成と伝播の問題です。私はあなたを招待します。さまざまな信号が送信される原因は何ですか?背景の詳細をご覧ください。
リモートホストには2つの関連プロセスがあります。
sshd
リモートプログラムの入出力をローカル端末に中継する ssh デーモン ( ) のインスタンスです。- ループを実行するシェルです
for
。
シェルはループの終わりに達したり、致命的なエラーが発生した場合は自然に死ぬことがあり、シグナルによって死ぬ可能性があります。問題は、シェルが信号を受信するのはなぜですか?
リモートシェルがパイプを介して接続されている場合sshd
(コマンドラインでコマンドを指定したときに発生)ssh
、終了します。信号パイプライン終了し、sshd
シェルがパイプに書き込もうとした場合。シェルがパイプに書き込まない限り、SIGPIPE を受信しません。ここでは、シェルは標準出力に何も書き込まないため、永久に持続する可能性があります。
-t
このオプションをsshに渡して、リモート側で端末をエミュレートし、この端末で指定されたコマンドを実行するように指示できます。その後、SSH クライアントが消えたら、sshd
接続を閉じて終了して端末を破壊します。端末デバイスが消えた場合、その中で実行されているすべてのプロセスはため息をつく。したがって、SSHクライアントをシャットダウンすると(kill
クライアントが実行されている端末を使用または閉じて)、リモートシェルはSIGHUP信号をエクスポートします。
この-t
オプションが渡されると、SSHもリレーします。知能を知らせる。Ctrl+を押すと、CリモートシェルがSIGINTを受け取ります。
答え2
コマンドを使用してpsuedo-ttyを割り当ててみてくださいssh
。
ssh -t $ip_address 'for n in 1 2 3 4 5; do sleep 10; echo $n >>/tmp/count; done'
SSH セッションを切断すると、プロセスは終了します。
これは疑似ttyなので、シェルの初期化時に構成ファイルのソースコードを取得できず、コマンドが非常に公開された環境に残ることがあります。.ssh/environment
環境変数(PATHなど)を定義するファイルを設定する必要があるかもしれません。 ~からman 1 ssh
Additionally, ssh reads ~/.ssh/environment, and adds lines of the format
“VARNAME=value” to the environment if the file exists and users are allowed
to change their environment. For more information, see the
PermitUserEnvironment option in sshd_config(5).
答え3
-t
ssh
クライアントのシャットダウンまたはシャットダウン時にリモートコマンドを終了させるオプションを使用する代わりに、標準入力を閉じるときに名前付きパイプをssh
使用してsshd
「EOFをSIGHUP」に変換できます(参照)。バグ396 - ptyが割り当てられていない場合、sshdは孤立プロセスになります。)。
# sample code in Bash
# press ctrl-d for EOF
ssh localhost '
TUBE=/tmp/myfifo.fifo
rm -f "$TUBE"
mkfifo "$TUBE"
#exec 3<>"$TUBE"
<"$TUBE" sleep 100 & appPID=$!
# cf. "OpenSSH and non-blocking mode",
# http://lists.mindrot.org/pipermail/openssh-unix-dev/2005-July/023090.html
#cat >"$TUBE"
#socat -u STDIN "PIPE:$TUBE"
dd of="$TUBE" bs=1 2>/dev/null
#while IFS="" read -r -n 1 char; do printf '%s' "$char"; done > "$TUBE"
#kill -HUP -$appPID
kill $appPID
rm -f "$TUBE"
'
答え4
無効にするには(デフォルトの動作として見える)、有効にする必要があります。SSHは生きているクライアントまたはサーバー側。
ssh-keep-alive-optionsのマニュアルページを見ると、デフォルトでは無効になっていることがわかります。