如何用Expect脚本匹配Unix多行cat /etc/hosts响应并写入本地
解决Expect脚本匹配多行netcat响应的方案
核心思路
远端执行cat /etc/hosts后会主动关闭netcat连接,利用Expect的expect eof事件可以完整捕获连接生命周期内的所有输出,这是最可靠的多行内容获取方式,无需复杂正则匹配换行或制表符。
完整Expect脚本示例
#!/usr/bin/expect -f # 设置超时时间,避免无限等待(根据实际场景调整) set timeout 30 # 启动netcat监听指定端口(示例用8080,可自行修改) spawn nc -l 8080 # 等待客户端连接成功的提示 expect "Connection from" # 发送命令,末尾加换行符触发远端shell执行 send "cat /etc/hosts\n" # 等待连接关闭(远端执行完命令后自动断开),捕获所有输出 expect eof # 清理输出:移除nc自带的连接提示行,只保留hosts文件内容 set raw_output $expect_out(buffer) set clean_hosts [regsub -all {Connection from [0-9.]* port [0-9]* accepted\r?\n} $raw_output ""] # 将清理后的内容写入本地文件 set file_handle [open "local_hosts_copy.txt" w] puts $file_handle $clean_hosts close $file_handle exit 0
关键细节说明
expect eof的作用:当远端执行完命令并关闭netcat连接时,Expect会触发eof事件,此时$expect_out(buffer)会保存从spawn启动到连接关闭的所有原始输出,包括换行、制表符等特殊字符。- 清理无关内容:netcat启动后会输出
Connection from xxx port xxx accepted这类提示,用regsub正则替换可以快速过滤掉这些无关行。 - 换行符处理:发送命令时必须加
\n(或\r,取决于远端终端配置),否则远端shell不会执行命令。
备选:多行正则匹配方案
如果不想依赖eof事件,也可以用兼容多行的正则直接匹配内容,利用[\s\S]*匹配所有字符(包括换行):
# 替换脚本中expect eof及后续内容 expect -re {([\s\S]*)\Z} set clean_hosts $expect_out(1,string) # 写入文件逻辑同上
内容的提问来源于stack exchange,提问作者molko
相关产品推荐
相关产品推荐

