bashスクリプトからプロセスをデタッチするにはどうすればよいですか?


18

スクリプトを終了するときにSIGINTがプロセスに転送されないように、bashスクリプトからプロセスをデタッチしようとしています。

disownターミナルでコマンドを直接使用しましたが、bashではdisownSIGINTの転送を停止しません。このスクリプトの目的は、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ツールにも移植可能なツールを使用しようとしています。


nohup正しい答えではありません。疑似コードまたはサンプルコードを追加して、必要なものをより正確に表示する必要があります。
ブルースエディガー

1
のようなツールを使用することにオープンscreenですか?
エリックルヌーフ

回答:


17

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" &

なぜnohup必要なのですか?違いは何であるnohup COMMAND &COMMAND &あなたの目標は、バックグラウンドでコマンドを実行すると、端末を解放するだけである場合は?
ジェームズWierzba

@JamesWierzba違いの1つは、シェルを終了した後でもコマンドを実行し続ける必要がある場合、nohupがその方法であるということです。ウェブには何千もの広範な説明があります。例えば、stackoverflow.com
questions / 15595374 /


4

私が見つけた解決策には、Annon Inglorionによって書かれ、彼のWebサイトからダウンロード可能な「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を格納しているファイルを使用して、切り離されたプロセスを直接強制終了します。


確認できる、detach驚異的になります。
AS

2

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

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 1at利用できませんでした(奇妙ですが、これは起こります...)。$(...)それほど古いシェルは必要ありません。そうでなければバックティックを使用してください。


これは危険なようです。複数のプロセスが同じ名前で実行されている場合、または別のプロセスにopenocdという単語が含まれている場合でも、pidのgreppingは予期しない動作をする場合があります。
オリオン

1
@オリオン:私はアイデアを与える簡単な例を挙げます、あなたが言及するこれらの懸念は簡単に取り除くことができます:atプログラムを起動し、代わりにファイルでそのpidを提供するスクリプトを開始し、メインスクリプトがそれを待つようにするファイルが表示され、そこからpidが読み取られます。
オリビエデュラック

もちろん、私の(非常に単純な)例では、右の列(通常$ 8)でawk内のテストでgrepを置き換える必要があります(列は、osとpsのバージョン/オプションによって異なります)
Olivier Dulac
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.