将登录的 shell 上存在的文件读取为字符串,并使用期望脚本执行循环



我有一个期望的shell脚本,用于使用ssh自动进行shell登录,登录后我在登录的shell上创建了一个文件,我想读取并显示登录服务器上存在的文件内容。

我期望的 scrip 看起来像这样 1. 使用 SSH 登录外壳 2. 在那里创建一个文件 3. 读取创建的文件的内容并显示它。

#!/usr/bin/expect
spawn telnet 10.10.10.10
expect "login:*"
send "XXXXXXr"
expect "Password*"
send "XXXXXr"
expect "#"
send "ls -lrt > tempr"
expect "#"
set f [open ./temp]
set entry [split [read $f] "n"]
close $f
expect "#"
foreach line $entry {
puts "$linen"
}
exit

它说不存在临时文件,因为它假定该文件存在于执行预期 scrip 的位置。但是我想读取我在登录的外壳上创建的文件。我正在使用Mac进行脚本编写。

您希望捕获命令的输出,而不是创建临时文件:

set cmd "ls -lrt"
send "$cmdr"
expect -re "$cmdrn(.*)rn#$"
set ls_output $expect_out(1,string)
puts $ls_output

我们发送命令,然后期望匹配正则表达式:

  • 我们发送的命令:ls -lrt
  • 换行符
  • :期望总是为换行符发回rn
  • 无论命令输出什么:(.*)
  • 换行符、提示字符#和文本结尾

第一组捕获括号中的文本显示在expect_out数组中,数组键1,string

如果您的提示不完全是没有前导或尾随字符的哈希字符,则需要相应地调整该正则表达式。

提示:在开发期望脚本时,启用调试,以便您可以看到哪些内容与您的期望模式匹配或不匹配:expect -d script.exp

问题是文件正在远程主机上创建,但您正在尝试在本地读取它。如果你在两者之间没有共享文件系统(非常不是默认的;如果你有,你就不会问这个问题!(,那是行不通的。

相反,您希望以易于消化的格式远程写出信息,然后在本地解析它。格式部分是您需要考虑前进的事情,但这是其余部分:

spawn telnet 10.10.10.10
expect "login:*"
send "XXXXXXr"
expect "Password*"
send "XXXXXr"
expect "#"
send "ls -lrtr"
# Create the accumulator so that won't be surprised if there's no remote output
set entry {}
# This is the multi-clause version of the expect command
expect {
"#" {
# Got a prompt; drop out of the expect
}
-re {^.*$} {
# Got some other line; save and wait for the next one
lappend entry $expect_out(0,string)
exp_continue; # <<< MAGIC; asks expect to keep waiting
}
}
foreach line $entry {
puts "$linen"
}
exit

几乎所有关于如何使用 Expect 自动化一些稍微棘手的事情的问题似乎最终都使用带有适当exp_continue调用的多子句版本的expect

ls -lrt > temp

在远程主机(telnet 服务器(上运行,但open ./temp在本地主机(telnet 客户端(上运行。您不能直接打开远程服务器上的文件。

最新更新