bash でサブシェルを作成する方法は何ですか?

bash でサブシェルを作成する方法は何ですか?

今のところ私が知っている主な方法は 2 つあります。

  • 明示的に: コマンドのリストを括弧で囲む

  • 暗黙的に: パイプライン内のすべてのコマンド

bash でサブシェルを作成する明示的または暗黙的な方法は他にもありますか?

答え1

からman bash

  • コマンドが制御演算子によって終了された場合&、シェルはサブシェル内でバックグラウンドでコマンドを実行します。シェルはコマンドの終了を待たず、戻りステータスは 0 になります。
  • コプロセスは、予約語が前に付いたシェルコマンドですcoproc
    コプロセスは、コマンドが & 制御演算子で終了したかのように、サブシェルで非同期的に実行されます。
  • シェル組み込みcompleteコマンド:-C command オプション付きで呼び出されると、commandサブシェル環境で実行され、その出力が可能な補完として使用されます。
  • コマンド置換、括弧でグループ化されたコマンド、および非同期コマンドは、シェル環境の複製であるサブシェル環境で呼び出されます。

答え2

「サブシェル」の意味によって異なります。また、「パイプライン内のすべてのコマンド」という項目の要点を理解していない可能性があります。 

走るときはいつでもどれでも(外部) プログラム (つまり、シェル組み込みではなくスクリプトまたはバイナリ実行可能ファイル) の場合、 を使用しない限り、サブプロセス (またはプロセス) で実行されます。シェルはプログラムをフォークして実行します。 は  、単独で行う場合と同様に、サブシェルを作成しません。exec programls | wclswc

興味深いのは、パイプラインにこれ​​を含めると、シェル組み込みサブシェルで実行する次の例を考えてみましょう。

$ 読み取り v# これはユーザーが入力した内容です。

$ エコー "$v"

$ エコークーガー | 読み取りv

$ エコー "$v"

2 番目のread vコマンドはパイプラインの一部であるため、サブシェルで実行されますecho cougar | read v。したがって、値cougarは失われ、$v最初の値が保持されます。

同様に、次のようなコマンド

$ echo foo | cd /

$ cd / | cat

$ echo foo | exit

$ exit | cat

メインシェルには影響しません。

関連情報