web-dev-qa-db-ja.com

bash:サブプロセスが失敗した場合に親プロセスのPIDを取得しないようにしました

(以前のタイトル-bash:コマンドをバックグラウンドで実行し、pidをキャプチャします)

注これは他の質問の[DUPLICATE]ではありません。これは、「コマンドが見つからない」などの原因でサブプロセスの開始に失敗して$!失敗したサブプロセスのpidではなく、呼び出しプロセスのpidに設定するか、 ""(null)。 -docsalvager

私はbash 4.1スクリプトを書いています...

  • バックグラウンドで別のスクリプト(または内部関数)を実行したい...
  • そして、そのバックグラウンドジョブのPIDをフォアグラウンドスクリプトの変数にキャプチャします...
  • ジョブが開始しない場合、変数はnull(つまり、 "")になるはずです。

バックラウンドジョブが常に開始される場合、これらのいずれかが機能します...

cmd &
VAR=$!

or...

( cmd & ); VAR=$!

cmdが実行されると、最後に開始されたコマンド($!)のpidが必要なものになり、$ VARが正しくなります。

ただし、cmdが開始しない場合、$ VARは最後のコマンドのpid before beforeになります。 =フォアグラウンドスクリプト自体のpidである可能性がある開始された。後で特定の条件下でプロセスを強制終了するためにcmdのpidが必要になるので、間違ったpidを取得してもうまくいかない可能性があります。

私が本当に必要なのは、バックグラウンドジョブが実行された場合にのみVARを変更することです。構文的に正しくないようなもの...

VAR=
( cmd & );  && VAR=$!

実装されたソリューション

コメントとジョセフRの答えは非常に役に立ちました。同様の問題を持つ人のために...

次のbash関数は、GtkDialog standbyスクリプトをバックグラウンドで実行します。それ自体がサブプロセスで実行される関数内にあるため、standbyスクリプトが失敗した場合にstandbyスクリプトのPIDではなく、呼び出しスクリプトのPIDを取得しないようにする必要がある分離が提供されているようです。 ...

function standbyBg () {
  ifHelpShow "$1" 'standbyBg
    Run standby (busy "throbber") in background and echo its pid.
    Example:
        standbyPID=$(standbyBg)
    Revised:
        20131123 docsalvager'  && return
  #
  standby  >/dev/null 2>&1  &
  echo $!
}
21
DocSalvager

ちょっとハックな回避策:

jobs &>/dev/null
cmd &
new_job_started="$(jobs -n)"
if [ -n "$new_job_started" ];then
    VAR=$!
else
    VAR=
fi

help jobsに注意を向けてくれた@terdonのコメントに感謝します。

8
Joseph R.