从主解释器调用从解释器中的隐藏命令

Invoke hidden commands in slave interpreters from master interpreter

我已经创建了一个安全解释器 (interp create -safe) 并且想通过 interp invokehidden 命令从主服务器 source 一个文件到从服务器。但是我一开始收到以下错误信息

..
invalid command name "pwd"
    while executing
"pwd"
  (file "C:/MyPkgFile.tcl" line 4)
invoked from within

这是因为,该文件在第 4 行包含以下代码

set usr_dir [file dirname [file join [pwd] [info script]]]

然后使用 interp expose,我授予了对命令 pwd 的访问权限。然后错误传播到 file 命令。再次,将命令 file 暴露给从机。现在,我得到了

not allowed to invoke subcommand dirname of file
    while executing
"file dirname [file join [pwd] [info script]]"

如何授予子命令的访问权限?我尝试了以下方法,

interp expose myslave file
interp expose myslave file dirname
interp expose myslave {file dirname}

运气不好。 :(。我怎样才能做到这一点?

我没想到自己会将这些命令暴露给奴隶,因为我是通过 invokehidden 从主人的控制中获取文件的。为什么会出现这种行为?

您需要公开正确的命令,并以使其有效的方式公开。这涉及相当接近 Tcl 实现中的一个更严重的错误特征:由于 Tcl 8.0 中的错误,隐藏的命令机制不能很好地与名称空间一起使用,并且从那以后修复它们并不是一个高优先级。

您还必须处理以下事实:rename 不会覆盖命令,并且 ::tcl::file::dirname 处已经有一个虚拟命令(即给出“not allowed to invoke subcommand dirname of file”错误信息;实际上,这就是虚拟命令所做的一切)。

# Grant the command back into the slave with a temporary name
interp expose myslave tcl:file:dirname DIRNAME
interp eval myslave {
    # Get rid of that dummy command
    rename ::tcl::file::dirname ""
    # Put the exposed command into place
    rename DIRNAME ::tcl::file::dirname
}

强烈 建议您在让任何不安全的代码在解释器中执行之前执行此操作。如果您需要 运行 两段不安全代码,并且只有一段可以访问 dirname 子命令,请创建两个从属并根据需要使用别名将它们连接在一起。