今のところ私が知っている主な方法は 2 つあります。
明示的に: コマンドのリストを括弧で囲む
暗黙的に: パイプライン内のすべてのコマンド
bash でサブシェルを作成する明示的または暗黙的な方法は他にもありますか?
答え1
からman bash
:
- コマンドが制御演算子によって終了された場合
&
、シェルはサブシェル内でバックグラウンドでコマンドを実行します。シェルはコマンドの終了を待たず、戻りステータスは 0 になります。 - コプロセスは、予約語が前に付いたシェルコマンドです
coproc
。
コプロセスは、コマンドが & 制御演算子で終了したかのように、サブシェルで非同期的に実行されます。 - シェル組み込み
complete
コマンド:-C command
オプション付きで呼び出されると、command
サブシェル環境で実行され、その出力が可能な補完として使用されます。 - コマンド置換、括弧でグループ化されたコマンド、および非同期コマンドは、シェル環境の複製であるサブシェル環境で呼び出されます。
答え2
「サブシェル」の意味によって異なります。また、「パイプライン内のすべてのコマンド」という項目の要点を理解していない可能性があります。
走るときはいつでもどれでも(外部) プログラム (つまり、シェル組み込みではなくスクリプトまたはバイナリ実行可能ファイル) の場合、 を使用しない限り、サブプロセス (またはプロセス) で実行されます。シェルはプログラムをフォークして実行します。 は 、単独で行う場合と同様に、サブシェルを作成しません。exec program
ls | wc
ls
wc
興味深いのは、パイプラインにこれを含めると、シェル組み込みサブシェルで実行する次の例を考えてみましょう。
$ 読み取り v 猫 # これはユーザーが入力した内容です。 $ エコー "$v" 猫 $ エコークーガー | 読み取りv $ エコー "$v" 猫
2 番目のread v
コマンドはパイプラインの一部であるため、サブシェルで実行されますecho cougar | read v
。したがって、値cougar
は失われ、$v
最初の値が保持されます。
同様に、次のようなコマンド
$ echo foo | cd /
$ cd / | cat
$ echo foo | exit
$ exit | cat
メインシェルには影響しません。