evalとexecの違いは何ですか?

evalとexecの違いは何ですか?

evalどちらexecもコマンドを実行するbash(1)コマンドに組み込まれています。

また、execいくつかのオプションがありますが、それが唯一の違いですか?彼らの背景はどうなりますか?

ベストアンサー1

evalexec全く違う獣です。 (両方ともコマンドを実行することを除いて、シェルで実行されるすべての操作も同じです。)

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

別のプロセスを実行するのではなく、現在のシェルがコマンドに置き換えられることを除いて、exec cmdrunとまったく同じことを行います。cmd内部的にsayを実行すると、子プロセスが作成され、/bin/ls子プロセスで実行されます。一方、それはfork()exec()/bin/lsexec /bin/lsいいえフォークですが、殻だけを交換するだけです。

比較する:

$ bash -c 'echo $$ ; ls -l /proc/self ; echo foo'
7218
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7219
foo

そして

$ bash -c 'echo $$ ; exec ls -l /proc/self ; echo foo'
7217
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7217

echo $$私が起動したシェルのPIDを印刷すると、リストに/proc/self私たちが実行したシェルのPIDが表示されます。ls通常、プロセスIDは異なりますが、execシェルとls同じプロセスIDを持ちます。また、execシェルが交換されたため、次のコマンドは実行されません。


一方:

$ help eval
eval: eval [arg ...]
    Execute arguments as a shell command.

eval引数は現在のシェルでコマンドとして実行されます。つまり、eval foo barjust と同じですfoo bar。ただし、変数は実行前に拡張されるため、シェル変数に格納されているコマンドを実行できます。

$ unset bar
$ cmd="bar=foo"
$ eval "$cmd"
$ echo "$bar"
foo

そうだろういいえこの変数が現在のシェルに設定されるように子プロセスを作成します。 (eval /bin/lsもちろん、サブプロセスは既存のプロセスと同様に作成されます/bin/ls。)

あるいは、シェルコマンドを出力するコマンドを持つこともできます。 Runningはバックグラウンドでエージェントを起動し、現在のシェルで設定し、サブプロセス(実行するコマンド)ssh-agentで使用できる複数の変数割り当てを出力します。sshしたがって、ssh-agent次から始めてください。

eval $(ssh-agent)

そして、現在のシェルは他のコマンドによって継承された変数を取得します。


もちろん、変数にcmdそのような内容が含まれている場合は、rm -rf $HOME実行eval "$cmd"したくありません。文字列内のコマンド置換などまで処理されるので、しなければならない本物eval使用前に入力内容が安全であることを確認してください。

誤ってevalコードとデータが誤って混在するのを防ぐことがよくあります。

おすすめ記事