tcl:eval 和 exec 混淆点
tcl: eval and exec confusing point
我对 Tcl 中的 exec
和 eval
有点困惑。在以下示例中:
set cmd "mkdir new_folder";
exec $cmd
无法使用错误消息:couldn't execute "mkdir new_folder" no such file or directory.
eval
有效
set cmd "mkdir new_folder";
eval exec $cmd
我也试过这种方法:
set cmd_1 "mkdir";
set cmd_2 "new_folder"
exec $cmd_1 $cmd_2
它也很好用。
那是什么原因呢?
由于您自己的评论中已经暗示,问题在于参数的解释。如果您仍然希望在单个字符串中使用命令,您可以使用扩展运算符 {*}
.
set cmd "mkdir new_folder"
exec {*}$cmd ;# Tcl 8.5 or higher
eval exec $cmd ;# alternative solution
这不仅适用于 exec
命令。一般规则是:如果一个命令接受多个参数,并说存储在变量 params
中,当您调用该命令时,必须扩展参数:
cmd {*}$params
。
因此,以下这些脚本是等价的
cmd param1 param2
和
set params "param1 param2"
cmd {*}$params
您真正需要注意的地方是您的参数之一是否包含空格。那样的话,eval
就不知道怎么办了:
% set cmd "mkdir 'dir with spaces'"
mkdir 'dir with spaces'
% eval exec $cmd
% exec ls -l
total 20
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 'dir
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 spaces'
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 with
你真正想做的是使用列表。然后 Tcl 准确地理解了单独的元素是什么
% set cmd [list mkdir "dir with spaces"]
mkdir {dir with spaces}
% exec {*}$cmd
% exec ls -l
total 24
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 'dir
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:53 dir with spaces
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 spaces'
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 with
我看到这个 post 是旧的,我只是在我的朋友问到这个问题时把我的答案放在里面。
所以想象一下你只是在 bash shell 中执行命令并想要创建一个目录。在这种情况下,你会 运行:
mkdir new_folder
但是现在想像一下如果您 运行 使用如下相同的命令会发生什么:
"mkdir new_folder"
当然如果会抛出一个错误说:
bash: mkdir new_folder: command not found
现在它与 TCL exec 命令相同,当您将所有内容作为单个参数传递给 exec 时,它以相同的方式传递给 bash:
- exec "mkdir new_filder" # 实际执行:
- "mkdir new_folder" # 在 bash 中然后 hense 会抛出一个错误
现在为什么 eval 有用?只是因为它在 TCL 中评估后删除了范围,而你实际上执行了:exec mkdir new_folder
希望对您有所帮助!
我对 Tcl 中的 exec
和 eval
有点困惑。在以下示例中:
set cmd "mkdir new_folder";
exec $cmd
无法使用错误消息:couldn't execute "mkdir new_folder" no such file or directory.
eval
有效
set cmd "mkdir new_folder";
eval exec $cmd
我也试过这种方法:
set cmd_1 "mkdir";
set cmd_2 "new_folder"
exec $cmd_1 $cmd_2
它也很好用。 那是什么原因呢?
由于您自己的评论中已经暗示,问题在于参数的解释。如果您仍然希望在单个字符串中使用命令,您可以使用扩展运算符 {*}
.
set cmd "mkdir new_folder"
exec {*}$cmd ;# Tcl 8.5 or higher
eval exec $cmd ;# alternative solution
这不仅适用于 exec
命令。一般规则是:如果一个命令接受多个参数,并说存储在变量 params
中,当您调用该命令时,必须扩展参数:
cmd {*}$params
。
因此,以下这些脚本是等价的
cmd param1 param2
和
set params "param1 param2"
cmd {*}$params
您真正需要注意的地方是您的参数之一是否包含空格。那样的话,eval
就不知道怎么办了:
% set cmd "mkdir 'dir with spaces'"
mkdir 'dir with spaces'
% eval exec $cmd
% exec ls -l
total 20
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 'dir
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 spaces'
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 with
你真正想做的是使用列表。然后 Tcl 准确地理解了单独的元素是什么
% set cmd [list mkdir "dir with spaces"]
mkdir {dir with spaces}
% exec {*}$cmd
% exec ls -l
total 24
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 'dir
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:53 dir with spaces
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 spaces'
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 with
我看到这个 post 是旧的,我只是在我的朋友问到这个问题时把我的答案放在里面。 所以想象一下你只是在 bash shell 中执行命令并想要创建一个目录。在这种情况下,你会 运行:
mkdir new_folder
但是现在想像一下如果您 运行 使用如下相同的命令会发生什么:
"mkdir new_folder"
当然如果会抛出一个错误说:
bash: mkdir new_folder: command not found
现在它与 TCL exec 命令相同,当您将所有内容作为单个参数传递给 exec 时,它以相同的方式传递给 bash:
- exec "mkdir new_filder" # 实际执行:
- "mkdir new_folder" # 在 bash 中然后 hense 会抛出一个错误
现在为什么 eval 有用?只是因为它在 TCL 中评估后删除了范围,而你实际上执行了:exec mkdir new_folder
希望对您有所帮助!