我已经在网上(包括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中正确完成这些工作的任何见解都非常感激,我对这种语言没有任何经验!
答案 0 :(得分:2)
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解释 - 本地 - 所以那里没有令人讨厌的意外。)