TCL exec echo不适用于环境变量

时间:2018-04-02 17:43:31

标签: environment-variables tcl

让我们说我有环境变量PO,值为1.
如果我使用LINUX echo命令,我得到:

tuple

但是,如果我使用TCL和exec,我不会得到插值:

>echo $PO
1

现在,如果我做一些更精细的事情,通过使用regsub将每个$ {varname}替换为[lindex array get env varname] 0],并使用substr,它可以工作:

>exec echo "\$PO"
$PO

我有一些角落案件,当然。但是为什么exec没有回馈shell会做什么?

2 个答案:

答案 0 :(得分:3)

  

为什么exec没有回馈shell会做什么?

因为exec不是shell。

从shell执行echo $PO时,echo不负责解析值。在调用$PO之前,shell会将echo转换为值。从shell调用它时,echo永远不会看到$PO

如果你试图模仿shell的功能,那么你需要做与shell相同的工作(或者,调用一个实际的shell来为你工作)。

答案 1 :(得分:2)

Tcl是一个很多更关注它的插值位置比Unix shell通常要小心。它使环境变量不受影响,因此您不会意外地绊倒它们,并且在调用子进程时执行的处理要少得多。这完全是设计的!

尽可能(除了少数例外)Tcl将参数传递给exec到它创建的子进程。它还具有引用字符串的标准机制,以便您可以在参数实际传递给exec之前准确控制发生的替换。这意味着当你这样做时:

exec echo "\$PO"

Tcl将执行其正常的替换规则并获得命令调度的这些确切参数:exececho$PO。然后调用exec命令,该命令使用一个参数echo启动$PO程序,该命令就是这样做的。 (贝壳通常首先替换该值。)如果您改为:

exec echo {$PO}
你会得到同样的效果。或者即使你做完了:

exec {*}{echo $PO}

你仍然最终将完全相同的字符输入exec作为其参数。如果你想在它上面运行shell,你应该明确地要求它:

exec /bin/sh -c {echo $PO}

大括号中的位有一个完整的(小)shell脚本,并将进行评估。你甚至可以做到这一点:

exec /bin/sh -c {exec echo '$PO'}

这有点无用,但它有效。

您也可以从自己的代码中进行任何替换。我目前最喜欢的Tcl 8.7(开发中)是:

exec echo [regsub -all -command {\$(\w+)} "\$PO" {apply {- name} {
    global env
    return $env($name)
}}]

好的,这完全是过度的,但由于你可以使用任何旧的复杂RE和脚本来进行替换,它是一个主要的动力工具。 (您可以在较旧的Tcl中使用string mapregsubsubst执行类似的操作,但这样做有点难度。)天空和您的想象力是唯一的限制。