Provided by: manpages-zh_1.5.2-1.1_all bug

NAME

       interp - 建立和操纵 Tcl 解释器

总览 SYNOPSIS

       interp option ?arg arg ...?
_________________________________________________________________

描述 DESCRIPTION

       这个命令建立一个或多个新的  Tcl 解释器,并使其与建立(它们的)解释器在相同的应用中共存。建立
       解释器的解释器叫做主解释器(master)而新解释器叫做从解释器(slave)。主解释器可以建立任意数目
       的从解释器,每个从解释器也可以自己建立增添的从解释器而成为它们的主解释器,这将导致解释器的
       一个等级层次(hierarchy)。

       每个解释器相对其他解释器是独立的: 它有给命令、过程、和全局变量的自己的名字空间。一个主解释
       器可以使用叫别名(alias)的机制建立它的从解释器与它自身间的连接。别名是在一个从解释器中的一
       个命令,调用它时,导致在它的主解释器或其他从解释器中调用一个命令。解释器之间的唯一其他连接
       是通过环境变量(env  变量),它通常被在这个应用中的所有解释器共享。注意给文件的名字空间(比如
       由 open命令返回的名字)不在解释器之间共享。提供显式的命令来共享文件和把到打开文件的引用从一
       个解释器转换(transfer)到另一个。

       interp命令还提供对安全(safe)解释器的支持。一个安全解释器是一个功能被严格限制了的从解释
       器,这样就可以执行不可信任的脚本而不用害怕它们毁坏其他解释器或这个应用的环境。例如,安全解
       释器不能访问所有 IO  通道建立命令和子过程建立命令。 详情参见下面的 SAFE INTERPRETERS (安全 │
       的解释器) 章节。未从安全的解释器中去除有危险的功能;但是,它们是隐藏的,所以只有可信任的解 │
       释器可以获得到它们的访问。隐藏命令的详细解释请参见下面的  HIDDEN  COMMANDS  (隐藏命令)  章 │
       节。可以使用别名机制来在从解释器和它的主解释器之间进行受保护的通信(类似于一个内核调用)。别 │
       名机制工作的详情参见下面的 ALIAS INVOCATION (别名调用)章节。

       一个限定的(qualified)解释器的名字是一个适当的 Tcl 列表,它包含在这个解释器层次中它的祖先的
       一个子集,终结于以它的直接上级(immediate)主解释器命名的字符串。解释器名字是相对于在其中使
       用它的哪个解释器的。例如,如果 a 是当前解释器的一个从解释器并且它有一个从解释器 a1,它依次
       有一个从解释器 a11,在aa11  的限定的名字是列表 a1 a11。

       下面描述的 interp命令接受限定的解释器名字作为参数;命令在其中求值的解释器总是可以作为 {}来
       引用(空列表或字符串)。注意除了通过别名之外,在一个从解释器中不可能通过名字引用一个主(祖
       先)解释器。还有,没有通过它可以引用在应用中建立的第一个解释器的全局名字。这两种限制的目的
       都是为了安全。

INTERP 命令 COMMAND                                                                               │
       使用  interp   命令建立、删除、和操纵从解释器,并在解释器之间共享或转换通道。依赖于 option
       参数,它可以有下列一些形式:

       interp alias srcPath srcCmd
              返回一个 Tcl 列表,它的元素是与叫做 srcCmd的别名有关的 targetCmdargs(在建立别
              名时指定所有这些值;在从解释器中实际的源命令如果被重命名的话可能与 srcCmd 不同)。

       interp alias srcPath srcCmd {}
              删除在从解释器中用  srcPath  标识的给 srcCmd  的别名。srcCmd 引用在其下建立别名的名
              字;如果 源命令已经被重命名,则删除重命名后的命令。

       interp alias srcPath srcCmd targetPath targetCmd ?arg arg ...?
              这个命令在一个从解释器和其他解释器之间建立一个别名(关于在一个从解释器和它的主解释器
              之间建立别名请参见下面的  alias 从命令)。在这个命令中,两个从解释器可以在调用这个命
              令的解释器底下的解释器层次中的任何位置。SrcPathsrcCmd       标识这个别名的来
              源。SrcPath  是一个 Tcl 列表,它的元素选择一个特定的解释器。例如,“a b”标识一个解释
              器 b,它是解释器 a  的一个从解释器,a解释器是调用(命令)的解释器的一个从解释器。一个
              空列表指定调用这个命令的解释器。srcCmd给出一个新命令的名字,将在源解释器中建立
              它。TargetPathtargetCmd  指定一个目标解释器和命令,和 arg   参数,如果有的话,给
              targetCmd 指定增补的参数,它们在 srcCmd 调用中指定的所有参数的前面。TargetCmd在这个
              调用的时候可以被取消定义(undefine)了,或者它已经存在了;它不由这个命令来建立。别名
              安排在源解释器中调用给定源命令的时候在目标解释器中调用给定目标命令。详情参见下面的
              ALIAS INVOCATION (别名调用)章节。

       interp aliases ?path?
              这个命令返回给在用 path 表示的解释器中定义的别名的所有源命令的名字一个 Tcl 列表。

       interp create ?-safe? ?--? ?path?
              建立用 path  标识的一个从解释器和叫做从命令(slave  command)的一个新命令。从命令的名
              字是 path的最后一个成员。在其中建立新的从解释器和从命令的解释器由从 path 中去除最后
              一个成员所获得的路径来标识。例如,如果 patha b c  则一个新的从解释器和叫做  c的
              从命令建立在用路径  a  b 标识的从解释器中。可以使用从命令先下面描述的那样操纵新解释
              器。如果省略了 path, Tcl 建立 interpx 形式的一个唯一的名字,这里的 x是一个整数,并
              用于解释器和从命令。如果指定了  -safe开关(或者主解释器是一个安全解释器),新的从解释
              器将建立成功能有限的一个安全解释器;否则从解释器将包含   Tcl     内置命令和变量的全
              集。使用  -- 开关来标记开关的结束;如果路径是象 -safe  这样的一个特殊的值的时候需要
              这个开关。这个命令的结果是新解释器的名字。一个从解释器的名字在它的主解释器的所有从
              解释器中必须是唯一的;如果在这个主解释器中用给定名字(标识)的一个从解释器已经存在则
              发生一个错误。

       interp delete ?path ...?
              删除用可选的 path  参数给出的零个或多个解释器,并且对于每个解释器,它还删除它的所有
              从解释器。这个命令还删除给每个被删除的解释器的从命令。对于每个  path 参数,如果叫这
              个名字的解释器不存在,这个名字将引发一个错误。

       interp eval path arg ?arg ...?
              这个命令用与 concat命令相同的方式串联所有的 arg 参数,接着在用 path  标识的解释器中
              把结果字符串作为一个    Tcl   脚本来求值。把这个求值的结果(如果发生错误的话,包括象
              errorInfoerrorCode  变量这样的错误信息)返回给调用(命令)的解释器。

       interp exists path
              如果在这个主解释器中存在用  path  指定的从解释器则返回   1,否则返回  0。如果省略了
              path,使用调用(命令)的解释器。

       interp expose path hiddenName ?exposedCmdName?                                             │
              在用 path 表示(denote)的解释器中,使隐藏的命令 hiddenName  暴露(expose),最终把它带 │
              回在一个新的exposedCmdName    名字之下(目前只接受没有任何::    的一个全局名字空间名 │
              字)。如果有目标名字的一个暴露的命令已经存在,这个命令失败。隐藏命令的详情参见下面   │
              的HIDDEN COMMANDS (隐藏命令)章节。                                                  │

       interp hide path exposedCmdName ?hiddenCmdName?                                            │
              在用 path 表示(denote)的解释器中,使暴露的命令 exposedCmdName  隐藏,并把它重命名成 │
              隐藏命令 hiddenCmdName,如果未给出 hiddenCmdName 则保持相同的名字。如果有目标名字的 │
              一个隐藏的命令已经存在,这个命令失败。目前 exposedCmdNamehiddenCmdName二者不能 │
              不能包含名字空间限定符,否则将引发一个错误。即使当前名字空间不是全局名字空间,仍在  │
              全局名字空间中查找要被 interp  hide隐藏的命令。这防止从解释器通过使当前的名字空间不 │
              同于全局名字空间(的方式),来愚弄主解释器去隐藏错误的命令。隐藏命令的详情参见下面    │
              的HIDDEN COMMANDS (隐藏命令)章节。                                                  │

       interp hidden path                                                                         │
              返回在用 path  标识的解释器中所有隐藏命令的名字的一个列表。                         │

       interp invokehidden path ?-global? hiddenCmdName ?arg ...?                                 │
              在由 path 表示的解释器中用提供的参数调用隐藏命令 hiddenCmdName 。对参数不(进行)替换 │
              或求值。如果存在  -global  标志,在目标解释器的全局层次上调用隐藏命令;否则在当前的 │
              调用框架  (frame)上调用它并且可以访问调用框架内部和外部的局部变量。隐藏命令的详情请 │
              参见下面的HIDDEN COMMANDS (隐藏命令)章节。

       interp issafe ?path?
              如果由 path 指定的解释器是安全的则返回 1,否则返回 0interp marktrusted path                                                                    │
              标记用 path  标识的解释器是可信任的。不暴露隐藏命令。这个命令只能在可信任的解释器中 │
              调用。如果由 path标识的解释器已经是可信任的,则这个命令没有影响。

       interp share srcPath channelId destPath
              在用 srcPath  标识的解释器和用 destPath 标识的解释器之间导致用  channelId标识的  IO
              通道变成共享的。两个解释器在这个 IO通道上由相同的权限。两个解释器必须关闭它来关闭低
              层的 IO 通道;在销毁一个解释器的时候自动关闭在这个解释器中可访问的 IO 通道。

       interp slaves ?path?
              返回与用  path  标识的解释器相关的所有从解释器的名字的一个  Tcl    列表。如果省略了
              path,使用调用(命令)的解释器。

       interp target path alias
              返回描述给一个别名的目标解释器的一个 Tcl 列表。用一个解释器路径和源命令名指定这个别
              名, 就象在上面的 interp alias 中那样。目标解释器的名字被返回为相对于调用(命令)的解
              释器的一个解释器路径。如果给这个别名的目标解释器是调用(命令)的解释器则返回一个空列
              表。如果给别名的目标解释器不是调用(命令)的解释器或是它的后代之一则生成一个错误。在
              调用这个命令的时候目标命令不是必须定义的。

       interp transfer srcPath channelId destPath
              导致用  channelId  标识的 IO 通道,在用 destPath 标识的解释器中变成可获得的,而在用
              srcPath 标识的解释器中变成不可获得的。

SLAVE 命令 COMMAND

       对于每个用 interp  建立的从解释器,在主解释器中建立名字与这个新解释器相同的一个新  Tcl  命
       令。可以使用这个命令调用在这个解释器上的各种操作。它有下面的一般形式:
              slave command ?arg arg ...?
       Slave  是解释器的名字,commandargs确定这个命令的具体行为。这个命令有效形式有:

       slave aliases
              返回一个  Tcl 列表,它的元素是在 slave 中的所有别名的名字。返回的名字是建立别名时使
              用的 srcCmd 的值(如果它们已经被重命名,则它可以同这个命令的当前的名字不相同)。

       slave alias srcCmd
              返回一个 Tcl 列表,它的元素是与叫做 srcCmd  的别名相关的 targetCmdargs(在建立
              这个别名的时候指定所有这些值;在从解释器中的实际的源命令如果被重命令则可能与
              srcCmd不同)。

       slave alias srcCmd {}
              在从解释器中删除给 srcCmd  的别名。srcCmd  参照在其下建立别名的那个名字;如果源命令
              已经被重命名,则删除重命名后的命令。

       slave alias srcCmd targetCmd ?arg ..?
              建立一个别名,当在slave  中调用 srcCmd  的时候, 在主解释器中调用 targetCmd 。把 arg
              参数作为补充的参数传递给 targetCmd   ,这些参数在  srcCmd  的调用中传递的任何参数之
              前。详情参见下面的ALIAS INVOCATION (别名调用)章节。

       slave eval arg ?arg ..?
              这个命令用与 concat 命令相同的方式串联所有的 arg  参数,接着在 slave 中把结果字符串
              作为一个  Tcl  脚本来求值。把这个求值的结果(如果有错误发生,包括象  errorInfoerrorCode  变量这样的错误信息)返回给调用(命令)的解释器。

       slave expose hiddenName ?exposedCmdName?                                                   │
              这个命令暴露在  slave 的隐藏的命令 hiddenName,最终把它带回在一个新的exposedCmdName │
              名字之下(目前只接受没有任何:: 的一个全局名字空间名字)。如果有目标名字的一个暴露的命 │
              令已经存在,这个命令失败。隐藏命令的详情参见下面的HIDDEN COMMANDS (隐藏命令)章节。  │

       slave hide exposedCmdName ?hiddenCmdName?                                                  │
              这个命令隐藏在从解释器中暴露的命令           exposedCmdName,并把它重命名成隐藏命令 │
              hiddenCmdName,如果未给出hiddenCmdName 则保持相同的名字。如果有目标名字的一个隐藏的 │
              命令已经存在,这个命令失败。目前 exposedCmdNamehiddenCmdName二者不能不能包含名字 │
              空间限定符,否则将引发一个错误。即使当前名字空间不是全局名字空间,仍在全局名字空间  │
              中查找要被隐藏的命令。这防止从解释器通过使当前的名字空间不同于全局名字空间(的方     │
              式),来愚弄主解释器去隐藏错误的命令。隐藏命令的详情参见下面的HIDDEN COMMANDS  (隐藏 │
              命令)章节。                                                                         │

       slave hidden                                                                               │
              返回在 slave 中所有隐藏的名字的一个列表。                                           │

       slave invokehidden ?-global hiddenName ?arg ..?                                            │
              这个命令在  slave 中用提供的参数调用隐藏的命令 hiddenName。对这些参数不进行求值或替 │
              换。如果给出了  -global标志,则在这个从解释器的全局层次上调用这个命令;否则在当前调 │
              用框架上调用它并可访问这个调用框架内部或外部的局部变量。隐藏命令的详情参见下面      │
              的HIDDEN COMMANDS (隐藏命令)章节。

       slave issafe
              如果从解释器是安全的则返回  1,否则返回 0slave marktrusted                                                                          │
              标记从解释器为可以信任的。只可以被可信任的解释器调用。这个命令不暴露在这个从解释器  │
              中的任何隐含命令。如果这个命令已经是可以信任的了,则这个命令没有影响。

安全解释器 SAFE INTERPRETERS

       一个安全解释器是一个功能受限制的解释器,所以执行从最恶毒的敌人那里来的任意脚本都是安全的而
       不用害怕这个脚本毁坏包围它的(enclosing)应用或你的计算环境的其余部分。要使一个解释器安
       全,要从这个解释器中删除特定的命令和变量。例如,删除在磁盘上建立文件的命令,和删除exec命
       令,因为它可通过子进程导致破坏。通过建立到主解释器的别名,它小心的检查它们的参数并提供对设
       施的一个安全子集的受限制的访问,可以提供对这些设施的有限的访问。例如,在一个特定的子目录中
       允许文件建立,和允许对仔细选择的和一个固定的程序的集合的子进程调用。

       通过给 interp create 命令指定  -safe开关来建立一个安全的解释器。进而,一个安全解释器建立的
       任何从解释器都是安全的。

       建立的安全解释器准确的有下列的内置的命令集:     after       append      array       binary
       break       case        catch       clock          close       concat      continue    eof
       error       eval        expr        fblocked       fcopy       fileevent   flush       for
       foreach     format      gets        global        history     if          incr        info
       interp      join        lappend     lindex      linsert     list        llength     lrange
       lreplace    lsearch     lsort       namespace     package     pid         proc        puts
       read        regexp      regsub      rename         return      scan        seek        set
       split       string      subst       switch      tell        trace       unset       update
       uplevel     upvar       variable    vwait while
       interp                    create                     建立一个安全解释器时下列命令是隐藏的: │
       cd          exec        exit        fconfigure    file        glob        load        openpwd         socket      source      vwait   以后这些命令可以作为   Tcl  过程或别名来重新建 │
       立,或用 interp expose暴露出来。

       除此之外,在一个安全解释器中不存在 env变量,所以不能同其他解释器共享环境变量。env   变量可
       能造成一次安全冒险,因为用户可能在某个环境变量中存储敏感信息。例如,PGP 手册建议在环境变量
       PGPPASS 中存储 PGP  私有密钥。让不可信任代码可以在安全解释器中访问这个变量将招致一次安全冒
       险。

       如果扩展被装载到安全解释器中,它们也可以限制它们自己功能来排除不安全的命令。对扩展的安全性
       的管理的讨论参见Safe-Tclload Tcl 命令的手册条目。

别名调用 ALIAS INVOCATION

       精心的设计了别名机制,所以在安全的从解释器中执行不可信任的脚本是安全的而别名的目标是一个可
       信任的主解释器。最保证安全性的最重要的事情是确保从从解释器传递到主解释器的信息在主解释器中
       永不被求值或替换;如果这种情况发生了,它将开启在从解释器中的某个邪恶的脚本来在主解释器中调
       用任意函数,这将危及安全。

       当从解释器中调用一个别名的源(命令)的时候,在分析这个命令时进行常规的  Tcl 替换。在源解释器
       中完成这些替换,就象对在这个解释器中的调用的其他命令一样。源命令的命令过程接受它的参数并把
       它们与给这个别名的    targetCmdargs   融合起来建立一个新的参数数组。如果   srcCmd的字
       是``srcCmd arg1 arg2 ... argN'',则新的字集将是``targetCmd arg arg ... arg arg1  arg2  ...
       argN''。这里的 targetCmdargs 是在建立别名的时候提供的值。接着用 TargetCmd来在目标解释器
       中定位(locate)一个命令过程,并且用新的参数集来调用这个命令过程。如果在目标解释器中没有叫做
       targetCmd 的命令则发生一个错误。在这个字上不进行补充的替换:不通过常规的 Tcl 求值机制,直接
       调用目标命令过程。所以在每个字上精确的进行一次替换:     在分析建立这个别名的命令的时候替换
       targetCmdargs,当在源解释器中分析这个别名的源命令的时候替换 arg1 - argN。

       在安全解释器中给别名写 targetCmds 的时候,给它的参数永远不被求值或替换是非常重要的,因为这
       将提供一种逃逸机制,使从解释器可以执行在主解释器中的任意代码。这将危及系统的安全。

隐藏命令 HIDDEN COMMANDS                                                                          │
       安全解释器严重的限制了在其中执行的 Tcl 程序可获得的功能。允许不可信任的 Tcl 程序访问这些功 │
       能是不安全的,因为它们可以在这个环境中被用于各种攻击。但是,有时在安全解释器的上下文中有使 │
       用危险的功能的合理需要。例如,有时一个程序必须 source 到解释器中。另一个例子是  Tk,在这里 │
       窗口被绑定到与一个特定解释器关联的窗口层次当中;一些潜在的危险函数,比如窗口管理,必须在这 │
       个解释器上下文中的那些窗口上进行。                                                         │

       interp  命令提供了对这个问题的一种隐藏命令形式的解决方案。不是从安全解释器中整个的删除危险 │
       的命令,而是隐藏这些命令,所以它们变成对在这个解释器中执行的    Tcl   脚本是不可获得的。但 │
       是,这个安全解释器的任何可信任的祖先可以使用 interp invoke,在这个安全解释器的上下文中,调 │
       用这些隐藏命令。隐藏命令和暴露命令驻留在分开的名字空间中。在一个解释器中可以定义叫相同名字 │
       的隐藏命令和暴露命令。                                                                     │

       在别名调用期间,在主解释器中调用的过程体中可以调用在从解释器中的隐藏命令。例如,在一个从解 │
       释器中可以给 source 建立一个别名。当在这个从解释器中调用它的时候,调用在主解释器中的一个过 │
       程来检查这个操作是否是允许的(比如,是否允许这个从解释器访问的它要求source  的文件)。接着这 │
       个过程在从解释器中调用隐藏的  source命令来实际装载(source)这个文件的内容。注意在从解释器中 │
       存在来着两个叫 source 的命令: 别名和隐藏命令。                                             │

       因为一个主解释器可以把调用一个隐藏命令作为处理一个别名调用的一部分,必须非常小心的避免对通 │
       过别名调用传递来的任何参数进行求值。否则,恶意的从解释器可以导致一个可信任的代表它们来执行 │
       危险的命令。这个主题的完整讨论参见ALIAS   INVOCATION    (别名调用)章节。要避免这个问题,对 │
       interp invokehidden的参数不要进行替换或求值。                                              │

       不允许安全解释器调用它自身中或它后代中的隐藏命令。这防止安全从解释器访问在自身中或它们的后 │
       代中的隐藏命令。                                                                           │

       一个可信任的解释器可以使用 interp exposeinterp  hide  来操纵一个解释器中的隐藏命令的集 │
       合。interp  expose  命令把在用 path 标识的解释器中一个隐藏命令移动到暴露命令的集合中,在这 │
       个过程中可能重命名这个命令。如果叫目标名字的一个暴露的命令已经存在,这个操作失败。类似     │
       的,interp  hide  把在这个解释器中的一个暴露命令移动到隐藏命令的集合中。不允许安全解释器在 │
       它自身中或它的后代中的隐藏命令和暴露命令的集合之间移动命令。                               │

       目前,隐藏命令的名字不能包含名字空间限定符,并且在你可以隐藏它之前必须首先把在一个名字空间 │
       中的命令重命令到全局名字空中。在全局名字空间中查找要被  interp hide 隐藏的命令。这防止从解 │
       释器通过使当前的名字空间不同于全局名字空间(的方式),来愚弄主解释器去隐藏错误的命令。       │

感谢 CREDITS

       这个机制基于由 Nathaniel Borenstein 和 Marshall Rose 实现的 Safe-Tcl 原型。

参见 SEE ALSO

       load(n), safe(n), Tcl_CreateSlave(3)

关键字 KEYWORDS

       alias, master interpreter, safe interpreter, slave interpreter

[中文版维护人]

       寒蝉退士

[中文版最新更新]

       2001/10/09

《中国 Linux 论坛 man 手册页翻译计划》:

       http://cmpp.linuxforum.net