web-dev-qa-db-ja.com

アンパサンド(&)を使用してバックグラウンドでサブプロセスを実行すると、bashスクリプトを実行してもターミナルに戻りません

Javaプロセスを実行する2番目のスクリプト(child.sh)を2回呼び出すスクリプト(parent.shと呼びます)があります。child.shスクリプトはバックグラウンドで実行されますparent.shの行末に&を配置します。ただし、parent.shを実行する場合は、Ctrl + Cを押してターミナル画面に戻る必要があります。これはどのような理由がありますか? child.shプロセスがparent.shプロセスの下で実行されているという事実があるので、parent.shは、子が停止するまで停止しませんか?

parent.sh

#!/bin/bash
child.sh param1a param2a &
child.sh param1b param2b &
exit 0

child.sh

#!/bin/bash
Java com.test.Main 
echo "Main Process Stopped" | mail -s "WARNING-Main Process is down." [email protected]    

ご覧のとおり、プロセスが終了したときにメールを送信したいので、バックグラウンドでJavaプロセスを実行したくありません。上記のように実行すると、機能の観点から問題なく動作します。 、しかし、parent.shを実行した後、ターミナルに戻す方法を知りたいです。

9
theGuardian

私がやったことは、parent.shを次のように変更することでした

#!/bin/bash
child.sh param1a param2a > startup.log &
child.sh param1b param2b > startup2.log &
exit 0

あなたの提案と問題の根本原因分析がなければ、私はこの解決策にたどり着きませんでした。ありがとう!

そして、私の不正確なコメントをお詫びします。 (入力がありませんでした、私は記憶から答えました、そして私は間違って覚えていました。)

8
theGuardian

Linux Documentation Project からの次のリンクは、child.shwaitコマンドの後にmailを追加することを提案しています。

http://tldp.org/LDP/abs/html/x9644.html

上記のドキュメントの要約

Within a script, running a command in the background with an ampersand (&)
may cause the script to hang until ENTER is hit. This seems to occur with
commands that write to stdout. It can be a major annoyance.

....
....

As Walter Brameld IV explains it:

As far as I can tell, such scripts don't actually hang. It just
seems that they do because the background command writes text to
the console after the Prompt. The user gets the impression that
the Prompt was never displayed. Here's the sequence of events:

1. Script launches background command.
2. Script exits.
3. Shell displays the Prompt.
4. Background command continues running and writing text to the
   console.
5. Background command finishes.
6. User doesn't see a Prompt at the bottom of the output, thinks script
   is hanging.

child.shを次のように変更した場合、この煩わしさは発生しないはずです。

#!/bin/bash
Java com.test.Main
echo "Main Process Stopped" | mail -s "WARNING-Main Process is down." [email protected]
wait

または、@ SebastianStiglerが上記の質問へのコメントで述べているように:

Add a > /dev/null at the end of the line with mail. mail will otherwise try to start its interactive mode.

これにより、mailコマンドはstdoutではなく/dev/nullに書き込みます。これにより、この煩わしさも解消されます。

お役に立てれば

4
ptierno

STDOUTはどこかに行く必要があるであるため、プロセスはまだ制御端末にリンクされていました。この問題は、ファイル(> startup.log)にリダイレクトすることで解決しました。

出力に興味がない場合は、STDOUTを完全に破棄します(>/dev/null)。

エラーにも関心がない場合は、両方を破棄します(&>/dev/null)。

ターミナルからログアウトした後もプロセスを実行し続けるには、Nohup —を使用します。これにより、プロセスが実行中から効果的に切断され、マシンを再起動するまでバックグラウンドで静かに実行されます。 (またはそうでなければそれらを殺します)。

Nohup child.sh param1a param2a&>/dev/null&

1
Tim