web-dev-qa-db-ja.com

アプリケーションがSCREENから遅滞なく実行されないのはなぜですか?

screenでアプリケーションを実行し、screenが終了してもアプリケーションを実行し続ける必要があるとします。次のコマンドは、「sleep 1」が追加されている場合にのみ機能します。 「sleep 1」がないと機能しないのはなぜですか?

screen -d -m -L sh -c 'DISPLAY=:0 Nohup zenity --info --text test >/dev/null 2>/dev/null &'
1
Igor Liferenko

これはタイミングの問題のようです。Nohupには、親の1つからシグナルが送信される前に、シグナルを無効にするのに十分な時間がありません。これは、screenコマンドの前にstrace -o /tmp/s -ffを追加してから、ログファイルの1つ/tmp/s.*に追加することで確認できます。

...
access("/bin/Nohup", X_OK)              = 0
stat("/bin/Nohup", {st_mode=S_IFREG|0755, st_size=36696, ...}) = 0
--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
+++ killed by SIGHUP +++

起動を簡素化できます。これは、&を必要とせずに機能します。

DISPLAY=:0 screen -d -m -L Nohup zenity --info --text test 

別の解決策は、親シェルにジョブ制御を使用するように依頼することのようです。これにより、バックグラウンドでSIGHUPが無効になるか、子Nohupがさらにオンになるのを待ってから終了するようです。元のコマンドでsh -cmの代わりにsh -cを使用するとうまくいくはずです。たとえば、これは私のために働きます

screen -d -m -L sh -cm 'Nohup zenity --info --text test >&/dev/null & echo'

一方、-cversonはそうではありません。 bashにはdisownコマンドがあり、ジョブ制御を使用している場合、バックグラウンドジョブをSIGHUPから保護しますが、これも機能するため、Nohupがなくても必要ないようです。 screenプロセスを実行したままにしないで:

screen -d -m -L sh -cm 'zenity --info --text test >&/dev/null </dev/null & echo'
1
meuh

Nohupをすべてを含むコマンドとして使用することは不可能です。すべての出力を抑制せずにNohup.outを削除することはできず、Nohup.outの代わりにscreenlog.0を使用することは不可能です。 Nohup.outはキャリッジリターンを保持しないためです。

Nohupを使用する代わりに、シェルのtrapを使用します。したがって、OPのコマンドは次のようになります。

screen -d -m -L sh -c 'trap "" HUP; DISPLAY=:0 zenity --info --text test >/dev/null 2>/dev/null &'
0
Igor Liferenko