$!コマンドラインでは機能しません

$!コマンドラインでは機能しません

私は次を実行していますbashコマンドラインプロンプトから直接:

$ PIDS= ;while read name; do (cd $name; npm install) & echo started install; PIDS+=($!); done < <(\ls); for pid in ${PIDS[@]}; do wait $pid; done;

わかりました:

-bash: !: event not found

!「$!」を最初に変数として見るのではなく、コマンド履歴置換を実行するためにシンボルが使用されているとします。


bashコマンドラインから直接実行する場合、最後のバックグラウンドプロセスのpidを取得する方法は?

答え1

4.3と4.4では問題を再現できないので、bash一般的な答えは次のようになります。

問題は、履歴の交換が開始されたとき!に発生します(デフォルトでは対話型シェルを介して有効になっています)。PIDS+=($!)!

履歴の無効化に置き換えるかset +H引用するか!(前の内容のためここでは望ましくない$)、その後にスペースを追加します!。 Bashのマニュアルは次のとおりです。

!空白、改行、キャリッジリターン、=または((組み込みのshoptを使用してextglobシェルオプションが有効になっている場合)が続かない限り、履歴交換を有効にします。

コマンドラインは次のようになります。

PIDS=()
while read name; do
    (cd "$name"; npm install) &
    echo started install
    PIDS+=( $! )
done < <(\ls)
wait "${PIDS[@]}"

メモ:

  • ここでは1行のコードに限定されない。
  • 変数の周りに正しい引用符を追加しました。
  • 同時に複数のPIDを待つことができます。

答え2

~からバッシュ変更ログ:

この資料では、bash-4.2-alphaのバージョンと以前のバージョンであるbash-4.1-releaseの間の変更について詳しく説明します。 (…)

3. Bashの新機能(...)

ゆう。歴史的拡張は、もはや$!変数拡張を拡張しない。

以前のバージョンのbashPIDS+=($!)に対処するにはPIDS+=($! )!

関連情報