eval
どちらexec
もコマンドを実行するbash(1)コマンドに組み込まれています。
また、exec
いくつかのオプションがありますが、それが唯一の違いですか?彼らの背景はどうなりますか?
ベストアンサー1
eval
exec
全く違う獣です。 (両方ともコマンドを実行することを除いて、シェルで実行されるすべての操作も同じです。)
$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
Replace the shell with the given command.
別のプロセスを実行するのではなく、現在のシェルがコマンドに置き換えられることを除いて、exec cmd
runとまったく同じことを行います。cmd
内部的にsayを実行すると、子プロセスが作成され、/bin/ls
子プロセスで実行されます。一方、それはfork()
exec()
/bin/ls
exec /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 bar
just と同じです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
コードとデータが誤って混在するのを防ぐことがよくあります。