expect
我在脚本中有以下内容
spawn cat version
expect -re 5.*.*
set VERSION $expect_out(0,string)
spawn rpm --addsign dist/foo-$VERSION-1.i686.rpm
该cat
命令正在正确获取版本,但它似乎正在添加新行。因为我期望输出如下:
dist/foo-5.x.x-1.i686.rpm
但我在开始时出现以下错误:
cannot access file dist/foo-5.x.x
-1.i686.rpm
为什么要在命令输出expect
中添加新行cat
?有什么方法可以不这样做或修复 cat 命令的输出?
答案1
TCL 可以直接读取文件,而不会出现以下复杂情况spawn cat
:
#!/usr/bin/env expect
# open a (read) filehandle to the "version" file... (will blow up if the file
# is not found)
set fh [open version]
# and this call handily discards the newline for us, and since we only need
# a single line, the first line, we're done.
set VERSION [gets $fh]
# sanity check value read before blindly using it...
if {![regexp {^5\.[0-9]+\.[0-9]+$} $VERSION]} {
error "version does not match 5.x.y"
}
puts "spawn rpm --addsign dist/foo-$VERSION-1.i686.rpm"
答案2
您很可能在文件末尾有一个换行符version
,因此expect
与其说是添加换行符,不如说它是盲目地按照您的指示执行操作。恕我直言,在生成命令之前调整期望脚本以删除任何换行符会更容易rpm
,并且即使在删除它之后,如果不同的编辑将终止换行符放回原处,也将确保您不会再次遇到此问题。
即使文件中没有终止换行符version
,我仍然建议您添加一个调用(当然,strip()
调整为正确的语法)来处理这种情况。expect
答案3
正如 thrig 所说,您应该直接读取该文件。另外,使用cat
,正如约翰所说,文件末尾会有一个换行符,并且\r\n
在通过 的 pty 时,这将变成 (回车符,换行符) spawn
。因此,您可以更改正则表达式模式以仅捕获这些字符:
expect -re "(5.*)\r\n"
set VERSION $expect_out(1,string)
请注意我们如何要求索引 1(捕获)()
,而不是 0(整个模式匹配)。
tcl
或者,您可以使用以下命令删除空格
set VERSION [string trim $expect_out(0,string)]
请注意,您在预期行中混淆了 glob 和 regexp 模式:5.*.*
因为 glob 模式将与您的匹配5.xx输入风格。使用-re
意味着您应该只使用正则表达式5.*
来匹配所有内容到最后。