如何在Tcl / expect中的exec命令中使用方括号(Linux)

时间:2014-04-30 19:37:19

标签: tcl exec expect square-bracket

我已经在网上(包括StackOverflow)搜索了一个小时,似乎无法想出这个简单的事情。我正在为一些自动化解决方案编写一个期望脚本,而且它非常小(自动创建加密的Truecrypt卷,使用expect / Tcl将/ dev / urandom中的熵数据提供给Truecrypt,因为这只能以交互方式工作)。

我的主要问题是:如何运行Tcl exec命令来启动包含方括号的系统命令,然后将输出提供给变量?像这样:

set entropyfeed [exec tr -dc [:graph:] < /dev/urandom | head -c 320]

所以这应该从/ dev / urandom读取伪随机数据,然后使用tr过滤掉所有不可打印的字符(“[:graph:]”!)并将前320个可打印字符返回到变量$ entropyfeed。这适用于任何其他不使用带方括号的参数的命令!

Tcl似乎总是将[]解释为一种反叛,试图将内部命令作为Tcl命令运行。我无法找到一种方法来正确地逃避该exec调用中的括号,并且无论我是否尝试\ [:graph:\]或{[:graph:]}或多个反斜杠等等,都可以按照我的意愿运行。我真的很想使用[:graph:]而不是像a-zA-Z0-9这样的模式。另外,我现在真的想要如何做到这一点!

set entropyfeed [exec tr -dc \[:graph:\] < /dev/urandom | head -c 320]

这不对......

set entropyfeed [exec tr -dc {[:graph:]} < /dev/urandom | head -c 320]

......这也不是。

set entropyfeed [exec tr -dc \\[:graph:\\] < /dev/urandom | head -c 320]

不。

set entropyfeed [exec tr -dc \\\[:graph:\\\] < /dev/urandom | head -c 320]

钠啊。所以只是拼命地在反斜杠中淹没那条线并没有帮助......

{[:graph:]}\\[:graph:\\]的情况下,它实际上会在屏幕上打印出我需要的字符(几乎成功了?)但是随后出现错误“孩子被杀:写在没有读者的管道上” 。当我在Bash上运行原始命令时,不会发生这种情况。在这种情况下,似乎数据被误导了,但我在这里不知所措。

对于如何在Tcl / expect中正确完成这些工作的任何见解都非常感激,我对这种语言没有任何经验!

2 个答案:

答案 0 :(得分:2)

是的,这很烦人。由于shell似乎没有被它打扰,你可以这样做:

set entropyfeed [exec sh -c {tr -dc '[:graph:]' < /dev/urandom | head -c 320}]

或者,如果您只想要一个随机字符串的可打印的ascii字符:

proc random_string {n} {
    for {set i 1} {$i <= $n} {incr i} {
        append data [format %c [expr {33+int(94*rand())}]]
    }
    return $data
}
set entropyfeed [random_string 320]

答案 1 :(得分:1)

这是正确的:

set entropyfeed [exec tr -dc {[:graph:]} < /dev/urandom | head -c 320]

除了输出管道的早期关闭(因为head如何工作)导致tr因信号而退出,exec选择了生成错误。 exec命令有时非常令人讨厌。

使用Tcl直接完成所有工作可能最简单:

set entropyfeed ""
set f [open /dev/urandom rb]
# Older versions of Tcl need:
#    set f [open /dev/urandom]
#    fconfigure $f -translation binary
while {[string length $entropyfeed] < 320} {
    set c [read $f 1]
    if {[string is graph $c]} {
        append entropyfeed $c
    }
}
close $f

这应该是完全相同的,除了它现在只依赖于系统设备而不是外部程序。 (你可以使用Tcl的内置RNG代替,但我们不会对它有多好做出任何形式的保证。除此之外它是线程本地的 - 或者说它是&#39 ; s解释 - 本地 - 所以那里没有令人讨厌的意外。)