Bashスクリプトからプロセスを分離する方法は?

Bashスクリプトからプロセスを分離する方法は?

スクリプトを終了するときにSIGINTがプロセスに渡されないように、bashスクリプトからプロセスを分離しようとしています。

disown端末で直接コマンドを使用しましたが、bashではdisownSIGINTが渡されるのを防ぎませんでした。このスクリプトの目的は、単一の呼び出しでopenocdを起動し、gdbを起動することです。スクリプトが終了しないため(gdbを実行しているため)、SIGINTはまだgdbからopenocdに渡されます。これは、SIGINTがgdbで一時停止コマンドとして使用されるために問題になります。

端末では次のようになります。

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

この順序で端末から呼び出されると、SIGINTはgdbからopenocdに渡されません。ただし、同じ呼び出しがbashスクリプトにある場合、SIGINTが渡されます。

どんな助けでも大変感謝します。

ps この問題は OS X で発生しますが、すべての Unix ツールにも移植可能なツールを使用しようとしています。

答え1

Bashスクリプトからプロセスを分離するには、次の手順に従ってください。

nohup ./process &

たとえば、(ctrl + c)を使用してbashスクリプトを停止したり、SIGINTシェルが終了した場合、SIGHUPプロセスは中断されずに正常に実行され続けます。stdout&はstderrログファイルにリダイレクトされますnohup.out

スタンドアロンコマンドの実行中に端末から出力を表示するには、次のようにしますtail

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

答え2

私には拒否するのにぴったりです。

command & disown

答え3

私が見つけた解決策は、Annon Inglorionによって書かれ、彼のウェブサイトからダウンロードできる「detach」というプログラムに関連しています。ウェブサイト

コンパイル後、次のスクリプトで使用できます。

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

最初の行は新しいプロセス(openocd実行)を作成し、後で使用できるようにプロセスIDをファイル(debug.pid)に保存します。これにより、Oliverの回答で提供されているpidのgrepの問題が回避されます。次のブロックプログラム(gdb)の終了時にpidが保存されているファイルを使用して、分離されたプロセスを直接終了します。

答え4

バックグラウンドで正常に実行されるプロセス、disown、nohupなどは通常、SIGINTなどのいくつかのシグナルのためにサブプロセスが終了するため、100%正常に実行されません。あなたがする必要があるのは、別のプロセスグループを使用することです。

#!/bin/bash

(set -m; child_process &)

while [ true ]; do
   sleep 30
done

disown/nohup/whateverを使用するのとは異なり、CTRL-Cとサブプロセスは引き続き実行されます。

関連情報