我对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
它也很好用。 那是什么原因?
答案 0 :(得分:5)
当你的一个参数包含空格时,你真正需要注意的地方。在这种情况下,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
答案 1 :(得分:3)
正如您在自己的评论中已经暗示的那样,问题在于参数的解释。如果您仍希望将命令包含在单个字符串中,则可以使用扩展运算符{*}
。
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
答案 2 :(得分:1)
我看到这篇文章很老了,我只是把答案放进去了,因为我的朋友问了这个问题。 因此,只需在bash shell中执行命令并想要创建目录,就可以对案例进行映像。在这种情况下,您将运行:
mkdir new_folder
但是现在想象如果运行相同的命令会发生什么:
"mkdir new_folder"
当然如果会抛出错误说:
bash:mkdir new_folder:找不到命令
现在它与TCL exec命令相同,当你将所有内容作为单个参数传递给exec时,它与bash一样:
现在为什么eval有帮助?只是因为它在TCL中评估后删除了范围,并且您实际执行:exec mkdir new_folder
希望这有帮助!