web-dev-qa-db-ja.com

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

これまでにわかっている主な方法は2つあります。

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

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

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

4
Nadim Hussami

man bashから:

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

それは、「サブシェル」の意味によって異なります。また、「パイプライン内のすべてのコマンド」の箇条書きの要点を逃している可能性があります。

あなたが実行するときはいつでもany(外部)プログラム(つまり、シェル組み込みとは対照的に、スクリプトまたはバイナリ実行可能ファイル) 、exec programを使用しない限り、サブプロセスで実行します。シェルはプログラムをフォークして実行します。 ls | wcは、lsおよびwcだけでサブシェルを作成することはありません。

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

$ v 
猫を読む #これはユーザーが入力した入力です。
 
 $ echo "$ v" 
 cat 
 
 $ echo cougar | v 
 
 $ echo "$ v" 
 catを読みます

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

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

$ echo foo | cd /

$ cd / | cat

$ echo foo | exit

$ exit | cat

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