アンパサンドを「可変化」する(プロセスのバックグラウンド)


9

アンパサンドを変数に入れ、それを使用してプロセスをバックグラウンドに送信する方法があるかどうかを知りたいです。

これは機能します:

BCKGRND=yes
if [ "$BCKGRND" = "yes" ]; then
    sleep 5 &
else
    sleep 5
fi

しかし、これら5つのラインを1つだけで達成するのはクールではないでしょうか。そのようです:

BCKGRND='&'
sleep 5 ${BCKGRND}

しかし、それはうまくいきません。BCKGRNDが設定されていない場合は機能しますが、設定されている場合はリテラル「&」として解釈され、エラーになります。


末尾のアンパサンドを使用した後echo $!、PIDを返します
noobninja

回答:


9

変数を使用して呼び出しをバックグラウンド化することはできません。変数の展開は、制御演算子(&&およびなど&)のコマンドラインが解析された後に行われるためです。

さらに別のオプションは、呼び出しを関数にラップすることです:

mayberunbg() {
  if [ "$BCKGRND" = "yes" ]; then
    "$@" &
  else
    "$@"
  fi
}

...そして、必要に応じて変数を設定します。

$ BCKGRND=yes mayberunbg sleep 3
[1] 14137
$
[1]+  Done                    "$@"
# or
$ BCKGRND=yes
$ mayberunbg sleep 3
[1] 14203
$
[1]+  Done                    "$@"
$ BCKGRND=no mayberunbg sleep 3
# 3 seconds later
$

edだい?+1とにかく、これは最もクリーンなソリューションです。
Stephen Kitt

笑@StephenKitt; 今ギアが回っています
ジェフシャラー

私はevalの答えが単純であることを気に入っていましたが、バックグラウンドにしたかった実際の実際のコマンドは非常に複雑で、変数が多すぎてevalを快適に使用できませんでした。@ jeff-schallerが、私が行った方向に私を向ける答えを出しました。ただし、関数の代わりに、コマンド全体を変数に入れ、彼のifステートメントスタイルを使用して、&を付けてまたは付けずにコマンドを実行しました。
BrowncoatOkie

11

物事を反転させ、「フォアグラウンド」を変動させることができます。

FOREGROUND=fg
sleep 5 & ${FOREGROUND}

設定するFOREGROUNDtrueまたはバックグラウンドでプロセスを実行するために空にします。(バックグラウンドで実行するFOREGROUNDようにtrueを設定することは、明らかに混乱します!適切な変数名は、読者のための練習として残されています。)


4
これはすばらしいことですが、ジョブ制御なしではシェルでは機能しません(つまり、set -m使用されない限りスクリプト)。
モスビー

9

あなたはおそらく使用する必要がありますeval

eval "sleep 5" "$BCKGRND"

eval与えられた引数をシェルに再評価させます。&したがって、リテラルは&コマンドの引数としてではなく、コマンドの最後として解釈され、コマンドはバックグラウンドに置かれます。


2
を含む回答にevalは、注意して処理する必要があるという警告が含まれている必要があります。たとえば、この回答を参照してください。
ラルフ、

"$BCKGRND"空の引数を評価することで問題が何であるかわかりません。
モスビー

2
この場合、 @ Ralfはまったく無関係です。evalについて特別なことは何もありません。たとえば、算術展開を介してコマンドを実行できます。たぶん、bash(または類似のシェル)を使用することに対する警告はまったくあるはずです;-)
mosvy

1
@Kusalananda evalは、実際の評価を行う前に、引数をスペースで結合します。ぜひお試しくださいeval printf "'{%s}\n'" foo "" "" ""。何かに関係なく、eval foo "" "" "" ""は完全にに似ています。eval fooIFS
モスビー

1
評価対象のコマンドに特殊文字が含まれている場合は、二重引用符で囲む必要がありますeval 'sleep $TIMEOUT' "$BACKGROUND"。そうしないと、変数が別の変数に展開されたり、特殊文字が含まれていたりすると、2倍に展開される可能性があります。また、ネストされた引用はトリッキーになる可能性があります。
Barmar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.