while ループを含む PuTTY リモート コマンド

while ループを含む PuTTY リモート コマンド

私は、リモート サーバーに SSH で接続して実行するいくつかの一般的なタスクを自動化しようとしています。このために、保存したいくつかのセッションで PuTTY とその「リモート コマンド」オプション (接続 > SSH) を使用しています。私のリモート コマンドは次のようになります。

~/scripts/test; $SHELL -l

実行されるスクリプトは保存されたセッションごとに異なり、異なるタスクを実行します。$SHELL -lスクリプトの実行が完了した後も、PuTTY セッションはアクティブなままになります。

私が実行しているほとんどのスクリプトでは、これらすべてが完璧に機能しています。ただし、Ctrl+C で終了するまで、while ループを使用して一連のコマンドを実行するスクリプトがあります。スクリプトは正常に開始しますが、終了すると PuTTY シェルはアクティブなままになりません。$SHELL -l実行されていないようです。

この動作を示すスクリプトの例は次のとおりです。

while true; do
echo "."
sleep 2
done

以下は手動で実行すると正常に動作し、2 番目のコマンドから期待どおりの出力が表示されます。

~/scripts/test; echo "done"

しかし、PuTTY の「リモート コマンド」の 2 番目のコマンドは実行されません。実際、リモート コマンドを を含むように変更するとecho、表示されなくなります。

~/scripts/test; echo "done"; $SHELL -l

私の質問は、リスト内の 2 番目のコマンドが手動で実行すると実行されるのに、リモート コマンドでは実行されないのはなぜか、ということだと思います。そして、もっと重要なのは、これに対して何ができるのかということです。

関連があるかどうかはわかりませんが、私は Ubuntu 14.04 で PuTTY を実行しています。

答え1

またはputty--sshこのコンテキストでは違いはないと思います -- リモート システムで実行するコマンドを実行すると、リモート SSH サーバーはコマンドをシェル コマンドとして実行します。

/bin/bash -c '~/scripts/test; $SHELL -l'

つまり、bashこのパイプラインを実行するインスタンスがリモート システム上に存在します。また、bash最初のインスタンスによって起動され、この「テスト」スクリプトを実行する別のインスタンスも存在します。

Control-C を入力すると、putty文字がリモート システムに送信され、TTY によって割り込み文字として解釈されます。その結果、TTY に接続されているプロセスに SIGINT (割り込み信号) が送信されます。これにより、これらのシェル プロセスの両方が中断され、両方とも終了します。親シェル インスタンスでは SIGINT を無視する必要があります。

SIGINT を無視する bash コマンドは次のとおりです。

trap "" INT

したがって、パイプラインの SIGINT を無効にするには、元のコマンドを次のように変更します。

trap '' INT; ~/scripts/test; $SHELL -l

しかし、これにより子プロセスの SIGINT も無効になり、「テスト」スクリプトが Ctrl-C の影響を受けなくなります。そのため、テスト スクリプトの SIGINT を再度有効にする必要があります。そのためのコマンドは次のとおりです。

trap INT

この行をテスト スクリプト自体に追加することも、パイプラインに追加することもできます。

trap '' INT; ( trap INT; ~/scripts/test ); $SHELL -l

ここで、Ctrl + C を押すと、「test」プロセスは中断されますが、コマンド パイプラインを実行している親プロセスは中断されません。

putty や ssh を使用せずにこれをテストできます。次のコマンドを実行し、「sleep」の実行中に Ctrl-C を押してみてください。

bash -c 'sleep 15; echo foo'                  # Ctrl-C kills sleep; doesn't print "foo"
bash -c 'trap "" INT ; sleep 15; echo foo'    # Ctrl-C has no effect
bash -c 'trap "" INT; ( trap INT; sleep 15 ); echo foo'    # Kills sleep, prints "foo"

答え2

putty リモート コマンドの ctrl+c は実際には ssh セッションを中断するため、残りのリモート コマンドは実行されないことが予想されます。セッションをアクティブのままにしておくことが目的であれば、無限ループだけで十分です。

関連情報