UNIXシェルはなぜですか?どうすれば解決できますか?

UNIXシェルはなぜですか?どうすれば解決できますか?

BASHや他のUNIXシェルについて私が気づいたことの1つは、基本的にそして一般的な方法で使用されるとき、ほとんどすべてのものに対してサブシェルを作成することです。

例えば

foo=$(grep "someword" /path/to/somefile | awk '{print $3}')

いくつかのテキストを変数にロードするために、2つの新しいbashセッションが作成されます。

a) シェルがなぜこのようなことをするのか?コマンドラインプログラムがファイルディスクリプタで動作している場合、ディスクリプタを提供するために新しい非対話型シェルセッションを作成する必要はありません。そうですか?

b)コマンド出力を変数にロードするときにこの問題を解決するための最良の方法は何ですか? Bashで次のことができることを知っています。

read -r -d '' < <(...)

サブシェルを使わずにコマンドで変数を設定することは可能ですが、これは非常に面倒で、より良い(そしてより移植性の高い)方法を探しています。 (言い換えれば、パイプとコマンドの置き換えの一般的な代替案を知っている人がいる場合は本当に良いでしょう。いいえサブシェルが関連しています。 )

注:「Perl / Python / Rubyユーザー」は「正しい」ソリューションである可能性がありますが、これらのソリューションにはファイル操作、外部コマンド呼び出しなどに多くの定型句コードが必要になる傾向があります。

編集:以下の回答に感謝します。ただし、プロセスの交換が新しいシェルをフォークする必要がある理由はまだ説明されていません。組み込みコマンドの場合でも:

$ builtin echo $(builtin echo $(builtin echo $BASH_SUBSHELL))
2

答え1

grepあるいは、同じコマンドを実行するにはawkシェルを分岐する必要があります。つまり、サブシェルを取得します。唯一の例外は、コマンドが組み込みコマンドの場合、またはコマンドが最後のコマンドの場合です。ただし、後者の場合は、動作を変更できる特定の条件(既存のトラップなど)では実行できない一部のシェルによって実行される最適化のみですexec。したがって、2つのサブシェル

foo=$(grep "someword" /path/to/somefile | awk '{print $3}')

サブシェルを防ぐにはいくつかの回避策があり、状況に応じて見つける必要があります。

答え2

a) に焦点を当てます。

注文の実行

foo=$(echo bar)

コマンドはコマンド置換を使用するため、サブシェルを起動します。これは、サブシェルが使用される環境として機能することを意味します。

注文する明示的にサブシェルを実行する、とても簡単。
ネストしてもまったく変わりません。


「シェルがなぜこのようなことをするのか」という質問に答えた後:
なぜこのようなことを尋ねますか?

これは興味深いトピックですが、あなたの目標が何であるかを完全に理解していません

  • 最適化されたbash実装を提案しますか?
  • フォークの数を減らしますか?パフォーマンス上の理由から?どんな審美的な理由で?これは、独立した環境(アドレス空間 - プロセスを含む)を提供する最速の方法です。
  • シェル構文を変更しますか?達成しようとしている目標は正確に何ですか?

必要に応じて、他のユーザーに質問に詳細を追加するよう依頼し、コメントを残してください。



~からman bash

COMMAND EXECUTION ENVIRONMENT
       [ ... ]

       Command substitution, commands grouped with  parentheses,  and  asyn‐
       chronous  commands  are  invoked  in a subshell environment that is a
       duplicate of the shell environment, except that traps caught  by  the
       shell  are reset to the values that the shell inherited from its par‐
       ent at invocation.  Builtin commands that are invoked as  part  of  a
       pipeline  are  also executed in a subshell environment.  Changes made
       to the subshell environment cannot affect the shell's execution envi‐
       ronment.

       [ ... ]

関連情報