web-dev-qa-db-ja.com

プロセスを完全に切り離す方法

プロセスを生成してトップレベルで実行し、シェルが終了してもプロセスが実行され続けるようにします。

Nohupがこれを行うと誤解していましたが、シェルを終了して(シェルは、lxcコンテナーであり、それにsshを実行します)、再度入ると、プロセスは終了します。

(pstreeを見ると)Nohupを使用したり、所有権を剥奪したりしても、プロセスはまだ呼び出しシェルの下にあるようです。

いくつかのオプションを試しましたが、setsidは機能しているようですが、ここでNohupで何か問題が発生していますか?

$ cat myproc
sleep 1234

$ myproc &
$ pstree -a | grep -B 3 "1234" | grep -v grep
  |-screen 
  |   |-bash -ls
  |   |   |-bash -ls
  |   |   |   `-sleep 1234


$ Nohup myproc &
$ pstree 
  |-screen 
  |   |-bash -ls
  |   |   |-pstree -a
  |   |   `-sh ./myproc
  |   |       `-sleep 1234

$ myproc &
$ disown $!
$ pstree -a | grep -B 3 "1234" | grep -v grep
  |-screen 
  |   |-bash -ls
  |   |   |-bash -ls
  |   |   |   `-sleep 1234

$ setsid myproc &
  |-sh ./myproc
  |   `-sleep 1234

成功。しかし、なぜNohupは同じことを達成しなかったのですか? Nohupをより正しく使用する方法はありますか?

5
Neil McGill

myprocのソースを提供していないため、診断は少し難しいですが、問題は " TTYの制御 "に関係していると思われます。 _sleep 100_を呼び出すだけの小さなシェルスクリプトを作成しました。 Nohupで実行しました:

_$ Nohup ./sleeper > sleeper.out &

[1] 25305
-bash-3.2$ jobs
[1]+  Running                 Nohup ./sleeper > sleeper.out &
-bash-3.2$ ps -l -p 25305
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S 429624 25305 18252  0 77   0 - 15961 wait   pts/0    00:00:00 sleeper
_

psの出力を見ると、「 [〜#〜] tty [〜#〜] "」という名前の列があります。 Nohupの少なくともいくつかのバージョン(上記で使用したものはGNU coreutils、バージョン5.97、比較的古い)からのものです)私が開始したbashシェルを終了したときsleeper、TTY列が「?」に変更されました。これは、sleeperに1つがなかったことを意味します。

myprocがTTYを制御していることから意図的に切り離されていない場合でも、stdoutに書き込もうとすると、SIGPIPEシグナルなどを取得する可能性があります。他のことも可能だと私には思えますが、思い出したりグーグルで検索したりすることはできません。

" daemonize "を見つけたりコンパイルしたりできる場合は、試してみてください。 myprocがコンパイルされている場合は、ソースを変更してdaemon(3)ライブラリ関数を呼び出すことができます。

3
Bruce Ediger

これには at を使用できます。

atユーティリティは、標準入力からコマンドを読み取り、それらをat-jobとしてグループ化して、後で実行します。

at-jobは、シェルの個別の呼び出しで実行され、環境変数を除いて、制御端末のない個別のプロセスグループで実行されます。 atユーティリティの実行時に有効な現在の作業ディレクトリ、ファイル作成マスク、およびその他の実装定義の実行時属性は、at-job実行されます。

echo myproc | at now

...動作しますが、一部のシステムでは、最初にそのatデーモンモニターを構成する必要があります。

2
mikeserv

プロセスを完全に切り離すには:

Nohup ./command &

stdoutとstderrは、Nohupが実行されたのと同じディレクトリにあるNohup.outという名前のファイルに書き込まれます。

ターミナルで出力を確認しながらデタッチコマンドを実行する場合は、tailを使用します。

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
Nohup ./command &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &
1
marc