「su -c <command>&」がハングアップせずにコマンドをバックグラウンドで実行できるように見えるのはなぜですか


11

私は、バックグラウンドプロセスで断続的に死ぬ問題を抱えていた同僚を助けていました。

サーバーにログインして実行することでバックグラウンドプロセスを開始していることがわかりました。

su - <user> -c '<command>' &

「あは」と叫びました。「コマンドを「&」で開始すると、制御端末を終了するときにハングアップします。これを行うには、nohupなどを使用する必要があります。このプロセスは、デーモンとしての実行をサポートする必要があります。」

上記のコマンドをテストして私のポイントを実証しましたが...動作しているようです:上記のコマンドを実行したターミナルを終了したときに、コマンドによって開始されたプロセスが終了しませんでした。

コマンドは、出力がファイルに送られるカスタムPythonスクリプトです。私の知る限り、スクリプトにはインテリジェントな「デーモン化」のような機能はありません。Wikipedia:Daemon(computing):Creationページにリストされているデーモンとして実行するために必要なことは何もしません。

このようにコマンドを実行すると、期待どおりに動作します。

<command> &
exit

上記の場合、ターミナルを終了すると、コマンドによって開始されたバックグラウンドプロセスが終了します。

私の質問はこれです:

  1. 端末が終了したときにプロセスが終了しないようにする「su--c&」を追加するとどうなりますか。制御端子、標準入出力などについて詳しく知りたい

  2. これは、このコマンドをバックグラウンドプロセスとして実行するという目標を達成するための合理的な方法ですか?そうでない場合、そうではありませんか?

私は社内でベストプラクティスを広めたいと思っていますが、私が行った推奨事項を実証およびバックアップできる必要があります。

何が起こっているのかも正確に理解したい。

回答:


12

ターミナルの死が原因でプロセスが強制終了される可能性がある方法はいくつかあります。

  1. 最初の方法は、カーネル内の端末ドライバーが、端末が制御端末である制御プロセスにSIGHUPシグナル送信することです。ほとんどの場合、制御プロセスは最初に端末で起動されるシェルであり、その制御端末はそのstdin、stdout、およびstderrが接続されているシェルです。プロセスがを呼び出すと、制御端末から切断されます。setsid

  2. 2番目の方法は、シェルがSIGHUPを受信すると、そのシグナルをサブプロセス(より正確には、バックグラウンドジョブ)に再送信することです。一部のシェル(ksh、bash、zsh)にはdisown、SIGHUPを特定のジョブに送信しないようにシェルに指示するビルトインがあります。

  3. 端末がなくなり、プログラムが端末から読み取ろうとすると、ファイルの終わりの状態(またはバックグラウンドジョブの場合はEIO)が通知されます。端末が消え、プログラムが端末に書き込もうとすると、書き込みはEIOエラーで戻ります。これらにより、プログラムが終了する場合があります。

したがって、suここでの変更点は、(2)通常は初期シェルがバックグラウンドジョブを強制終了することですが、そのバックグラウンドプロセスは別のユーザーとして実行されているため、シグナルを配信できず、バックグラウンドプロセスが存続します。


rootユーザーが実行するのを見てきましたchroot --userspec root:root / sh -c "exec some_forever_process" &。ジョブは同じユーザーとして実行されており、nohup前後に明示的ではありませんdisown。では、この場合、終了時にシグナルを配信できないのはなぜですか?
Toddius Zho 2018

@ToddiusZho Presumable some_forever_processは永久に実行することを意図していたため(デーモン)、ターミナル出口からSIGHUPを受信しないようにします(独自のプロセスグループで実行することにより)。
Gilles「SO-悪をやめ

bash / tailはSIGHUPから保護しませんが、それでも機能します: `` `local $ ssh root @ REMOTE_HOST remote#chroot --userspec root:root / sh -c" exec bash -c 'tail -f / dev / null '"&[1] 6376リモート#ps -p $!--no-heading -o pid、uid、command -ww 6376 0 tail -f / dev / null remote#exit local $ ssh root @ REMOTE_HOST remote#ps -p 6376 --no-heading -o pid、uid、command -ww 6376 0 tail -f / dev / null `` `
Toddius Zho
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.