ssh 経由でログインするユーザーのデフォルト シェルとして機能する bash スクリプトがあります。netcat を使用してファイルを送信するオプションの 1 つを含むメニューを提供します。
私が使用している組み込み Linux の netcat には -w オプションがないため、ユーザーがファイルを送信せずに ssh 接続を閉じると、netcat コマンドは永遠に待機します。
スクリプトが netcat コマンドを強制終了して正常に終了できるように、ユーザーが突然接続を閉じたかどうかを知る必要があります。
私がこれまでに試したこと:
- SIGHUP のトラップ: 発行されません。私が見つけた発行された唯一のシグナルは SIGCONT ですが、信頼性が高く移植性があるとは思いません。
- read コマンドの -t オプションをいじって、クローズされた stdin を検出する: これは、埋め込まれた read コマンドのばかげたバグ (最初の呼び出しでのみタイムアウト) がなければ機能します。
編集:
コメントの質問に答えて、状況をさらに説明しようと思います。
私が持っているコードは次のとおりです。
nc -l -p 7576 > /dev/null 2>> $LOGFILE < $TMP_DIR/$BACKUP_FILE &
wait
私は SIGINT と SIGTSTP を無視していますが、すべてのシグナルをトラップしようとしましたが、受信したのは SIGCONT だけです。
bash の man ページを読むと、SIGHUP をスクリプトと netcat の両方に送信する必要があり、停止したジョブに SIGCONT を送信して、確実に SIGHUP を受信できることがわかりました。
待機するとスクリプトが停止したと見なされるため、SIGCONT を受け取りますが、同時に待機が何らかの形で SIGHUP を消費します。
そこで、スリープの待機を変更しようとしましたが、SIGHUP と SIGCONT の両方が受信されました。
問題は、待機が SIGHUP をブロックしているのはなぜですか?
編集2:解決
-t オプションを使用して read ビルトインを使用してクローズド stdin をポーリングして解決しました。read ビルトインのバグを回避するために、新しい bash で生成します (bash -c "read -t 3 dummy")。