web-dev-qa-db-ja.com

プロセスをbashスクリプトから切り離すにはどうすればよいですか?

スクリプトを終了したときにSIGINTがプロセスに転送されないように、bashスクリプトからプロセスを切り離そうとしています。

ターミナルで直接disownコマンドを使用しましたが、bashではdisownによってSIGINTの転送が停止されません。このスクリプトの目的は、openocdを起動してから、1回の呼び出しでgdbを起動することです。スクリプトは終了しない(gdbを実行している)ため、SIGINTはgdbからopenocdに転送されますが、これはSIGINTがgdbのhaltコマンドとして使用されているため問題です。

ターミナルでは次のようになります:

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

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

どんな助けでも大歓迎です。

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

19
user2328113

プロセスをbashスクリプトから切り離すには:

Nohup ./process &

SIGINT(ctrl + c)を使用してbashスクリプトを停止した場合、またはシェルがSIGHUPの送信などを終了した場合、プロセスは問題にならず、通常どおり実行されます。 stdoutstderrはログファイルにリダイレクトされます:Nohup.out

端末で出力を確認しながら、切り離されたコマンドを実行する場合は、tailを使用します。

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
Nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &
16
marc

私にとって、これはdisownで完全にうまく機能します

command & disown
12
ManuelSchneid3r

私が見つけた解決策には、Annon Inglorionによって作成され、彼からダウンロード可能な「detach」というプログラムが含まれています website

コンパイルすると、次のようにスクリプトで使用できます。

$ ./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)に保存します。これにより、オリバーの回答で提供されているpidのgreppingの問題が回避されます。次のブロッキングプログラム(gdb)を終了すると、pidを格納しているファイルを使用して、切り離されたプロセスを直接強制終了します。

4
user2328113

シンプルでポータブルなソリューション:

_echo "openocd" | at now #openocd starts now, but via the at daemon, not the current Shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb
_

いくつかの移植性の警告:psオプションはOSに依存します!代わりに、_{ ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1_のバリアントを使用できます。 atを使用できませんでした(奇妙ですが、これは起こります...)。 $(...)は、それほど古いシェルではなく、バッククォートを使用する必要があります。

2
Olivier Dulac