それで、自動化されたスクリプトの一部から、ハングした SSH 接続が残っている理由を不思議に思っていたところ、奇妙な問題に遭遇しました。SSH を PTY なしで使用すると、出力パイプが閉じられても終了しません。これはすでに他のいくつかの質問で議論されていますが、適切な回答は見つかりませんでした。-t
オプションを使用するようにアドバイスする人もいますが、PTY が要求され、パイプが機能しません。
とにかく、私は問題を次の最小限の例にまで縮小しました。
#this works
cat /dev/zero |false
#this never terminates
ssh user@host "cat /dev/zero" |false
SSH が、すでにデッド パイプ (false の原因となったパイプ) への書き込みから発生する SIGPIPE を無視する理由、またはこれを正しく「動作」させる方法はありますか?
SIGPIPE をリモート ホストに「中継」する必要はないことに注意してください。単に ssh クライアントを終了するだけで (SIGPIPE を無視しない場合はまさにこれが発生します)、複雑さが少なくなり、いくつかの「より正確な」仮定に基づいて同じ結果が得られます。
アイデアをありがとうございます!
-mk
編集: Sun_SSH サーバーでのみ発生します。文書化されていない問題のようです。適切な回避策を探しています。
答え1
自分の質問に答えると、これは Sun SSH の既知の問題です。私が見つけた最善の回避策は、出力で「Sun_SSH」を検出しssh -V
、次のようなものを適用することです。
#!/bin/bash
# ....
( ssh host 'localCommand' | remoteCommand || pkill -P $BASHPID )
他のシェルやより単純な状況 (シェルに他の子プロセスがない場合) では、$$
の代わりにを使用することもできます。$BASHPID