将登录shell中存在的文件读入字符串并使用expect脚本执行循环

问题描述 投票:0回答:3

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

我希望脚本看起来像是这样做1.使用ssh登录shell 2.在那里创建一个文件3.读取创建文件的内容并显示它。

#!/usr/bin/expect

spawn telnet 10.10.10.10
expect "login:*"
send "XXXXXX\r"
expect "Password*"
send "XXXXX\r"
expect "#"
send "ls -lrt > temp\r"
expect "#"
set f [open ./temp]
set entry [split [read $f] "\n"]
close $f
expect "#"
foreach line $entry {
    puts "$line\n"
}
exit

它说没有临时文件,因为它假定文件存在于执行expect脚本的位置。但我想读取我在登录shell中创建的文件。我正在使用Mac进行脚本编写。

shell unix ssh tcl expect
3个回答
1
投票

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

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

spawn telnet 10.10.10.10
expect "login:*"
send "XXXXXX\r"
expect "Password*"
send "XXXXX\r"
expect "#"
send "ls -lrt\r"

# 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 "$line\n"
}
exit

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


2
投票

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

set cmd "ls -lrt"
send "$cmd\r"
expect -re "$cmd\r\n(.*)\r\n#$"
set ls_output $expect_out(1,string)
puts $ls_output

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

  • 我们发送的命令:ls -lrt
  • 换行:期望总是发回\r\n换行。
  • 无论命令输出如何:(.*)
  • 换行符,提示字符#和文本结尾

第一组捕获括号中的文本出现在expect_out数组中,数组键为1,string

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

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


1
投票

ls -lrt > temp在远程主机(telnet服务器)上运行,但open ./temp在本地主机(telnet客户端)上运行。您无法直接在远程服务器上打开文件。

© www.soinside.com 2019 - 2024. All rights reserved.