问题描述
在此链接中,我阅读了 for 循环管理,除了 https://tcl.tk/man/tcl8.6/TclCmd/for.htm
如果你调用 expect 并将代码粘贴进去,你会得到正确的行为:
@gigi:~$ expect
expect1.1> for {set x 0} {$x<10} {incr x} {
puts "x is $x"
}+> +>
x is 0
x is 1
x is 2
x is 3
x is 4
x is 5
x is 6
x is 7
x is 8
x is 9
expect1.2>
相反,如果您从 bash 脚本传递它,则会出错:
^@gigi:~expect -d << EOD
> for {set x 0} {$x<10} {incr x} {
> puts "x is $x"
> }
> EOD
expect version 5.45.4
argv[0] = expect argv[1] = -d
set argc 0
set argv0 "expect"
set argv ""
executing commands from command file
missing operand at _@_
in expression "_@_<10"
(parsing expression "<10")
invoked from within
"for {set x 0} {<10} {incr x} {
puts "x is "
为什么这个例子的工作方式不同?
解决方法
您遇到的问题是 bash
扩展了 here-doc 中的变量,在将脚本传递给 expect
之前将这些变量放入其中。来自 bash
联机帮助页:
此处文档的格式为:
[n][-]词
此处-文档
分隔符
无参数和变量扩展、命令替换、算术
扩展或路径名扩展是对 word 进行的。如果任何部分
word 被引用,分隔符是对 word 引用删除的结果,
并且此处文档中的行未扩展。如果词是
未加引号,此处文档的所有行都受参数影响
扩展、命令替换和算术扩展,字符
序列 \
这意味着一种解决方法是使用 expect -d << 'EOD'
而不是 expect -d << EOD
。
expect -d << 'EOD'
for {set x 0} {$x<10} {incr x} {
puts "x is $x"
}
EOD
另一个(劣等的!)是反斜杠引用 $
字符;它是低劣的,因为真正的期望脚本通常包含自己的反斜杠,事情会变得非常丑陋和复杂。但是,最好这样做:
将expect 脚本放在它自己的文件中, 说myfile.exp
,并像这样调用它:expect -d -f myfile.exp
。试图将 Tcl 代码放在 Bash 脚本中是自找麻烦。
请注意,这确实意味着从 bash 传递变量有点尴尬。但是您可以通过大大提高编码的理智而获益。