次のコマンドを評価するためにシェルプロセスを作成して評価が機能しますか?

次のコマンドを評価するためにシェルプロセスを作成して評価が機能しますか?

で次のコマンドを評価するeval <command>方法は?eval

  • eval評価用のシェルサブプロセスを作成しますか<command>

  • それ以外の場合は、eval現在のシェルプロセスを使用して評価しますか?

気づく

  • eval組み込みプロセスなので、それeval自体では子プロセスは作成されません。
  • <command>実行前に子プロセスが組み込み<command>プロセスであるかどうかに応じて、それを実行するために作成することも、生成しないこともあります。

上記のコマンドを評価するために使用されるシェルサブプロセスは、コメントに記載されている2つのうちの1つではありません。

ありがとうございます。

答え1

うまくいくのは、evalパラメータの解析、変数の拡張などを実行してから、結果の文字列を正常に実行することです。

たとえば、次のようになります。

$ i=ls
$ eval $i

これは次のようにeval置き換えられます。$ilsそれからls通常どおりコマンドを実行します(その後、プロセスが実行されfork()ます)。exec()ls

しかし、そうすれば

$ i="echo hello"
$ eval $i
hello

echo helloこれは組み込みプロセスとして実行されるため、新しいプロセスは作成されません。

変数を設定すると、シェルが作成されないことがわかります。

$ a=0
$ i="a=100"
$ eval $i
$ echo $a
100

$a現在のシェル内で実行されている場合にのみ100に設定できます。

したがって、これはeval実際にパーサ自体であり、現在のシェルで行われます。結果この文字列は、他のコマンドと同様に、新しいプロセスを作成することも、生成しないこともあります。

答え2

以下で何が起こっているのかわかりませんが、実際には次のように動作します。source somefile新しいプロセスを作成せずに、現在のシェルプロセスでこれらのコマンドを実行します。

そして私は「コマンド」の代わりに「文字列」という言葉を使います。なぜならこれはまさに文字列だからです。これは機能しますが、次のコマンドはありません。

$ eval ""

あるいは、これは技術的にコマンドではありません。

$ eval "x(){ echo test;}"
$ x
test

そして常に新しいプロセスを作成するわけではないことを示すために(したがって私はウィリアムの意見に同意しません):

ターミナルから:

$ echo $$
9983
$ eval "sleep 100"  

もう一つ:

$ ps -ef --forest
peter     9983  2840  0 14:21 pts/41   00:00:00  \_ /bin/bash
peter    17339  9983  0 14:26 pts/41   00:00:00  |   \_ sleep 100

しかし、これを行うには、次の理由があります。

$ eval 'sleep 100' &
[1] 20675

$ ps --forest
  PID TTY          TIME CMD
 9983 pts/41   00:00:00 bash
20675 pts/41   00:00:00  \_ bash
20676 pts/41   00:00:00  |   \_ sleep
20757 pts/41   00:00:00  \_ ps

答え3

評価はこれだけのために新しいプロセスを作成しませんeval

代わりに、Evalは-引数接続を使用してパーサーを再実行しますeval

これにより、解析された結果が同じシェルで実行されます。ただし、引数がコマンドのサブシェルを生成する必要がある場合は、これが行われます。

したがって、evalの主な目的はパーサーを再実行することです。

答え4

これを試してみてください:評価中と$$評価前の間を拡張します。''$$""

$ eval /bin/echo '$$' "$$"
17899 17899

したがって、両方とも同じプロセスで拡張されるため、evalで始まるサブシェルはありません。私はシェルではなく関数echoを使用しました。

関連情報