我一直在尝试获取一个Expect / bash脚本,该脚本可以读取CSV文件的每一行并提取主机名地址和密码;因为对于我尝试访问的每个MikroTik,这些都是不同的。
我最近将一个auto.rsc文件发送到了数千个用作住宅解决方案的MikroTik路由器。该文件填满了硬盘驱动器(它进行了IP扫描,并创建了一个日志来完成任务。)由于没有可用空间,因此无法发送其他auto.rsc文件来清除日志。
我想出的解决方案是使用Expect脚本登录到这些脚本并删除auto.log文件。我的RSA脚本成功完成了此任务。
set timeout 3
set f [open "dynuList.txt"]
set dynu [split [read $f] "\n"]
close $f
foreach dynu $dynu {
spawn ssh -o "StrictHostKeyChecking no" -i mtk4.key admin+t@$dynu
expect {
"> " { send "\:do \{ file remove push.auto.log \} on-error\=\{ \[\] \}\r" }
"Connection refused" { catch {exp_close}; exp_wait; continue }
eof { exp_wait; continue }
}
expect ".*"
close
wait
}
我遇到问题的脚本如下:
n=`wc -l hostPasswordDynuList.csv | awk '{print$1}'`
i=1
while [ $i -le $n ]
do
host='awk -F "," 'NR==$i {print $1}' hostPasswordDynuList.csv'
password='awk -F "," 'NR==$i {print $2}' hostPasswordDynuList.csv'
./removeLogExpect.sh $host $password
i=`expr $i + 1`
done
应将变量传递给此期望脚本
#!/usr/bin/bash/expect -f
set timeout 3
set host [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh -o "StrictHostKeyChecking no" admin+t@$host
expect {
"password: " { send $password"\r" }
"Connection refused" { catch {exp_close}; exp_wait; continue }
eof { exp_wait; continue }
}
expect {
".*" { send "\:do \{ file remove push.auto.log \} on-error\=\{ \[\] \}\r" }
}
expect ".*"
close
wait
我希望脚本能够连接然后登录到每个没有RSA密钥设置的MikroTik,然后再命令清除auto.log文件。就目前而言,脚本似乎并没有将变量传递给期望值的一半。任何帮助将不胜感激。
答案 0 :(得分:2)
expect是Tcl语言的扩展,它是一种功能齐全的编程语言:它可以读取文件并解析逗号分隔的字段。不需要效率低下的Shell脚本来多次调用您的期望程序
#!/usr/bin/bash/expect -f
set timeout 3
set file hostPasswordDynuList.csv
set fh [open $file r]
while {[gets $fh line] != -1} {
lassign [split $line ,] host password
spawn ssh -o "StrictHostKeyChecking no" admin+t@$host
expect {
"password: " { send $password"\r" }
"Connection refused" {
catch {exp_close}
exp_wait
continue
}
eof {
exp_wait
continue
}
}
expect ".*"
send ":do { file remove push.auto.log } on-error={ \[\] }\r"
expect ".*"
exp_close
exp_wait
}
close $fh
有关Tcl内置命令的文档,请参见https://tcl.tk/man/tcl8.6/TclCmd/contents.htm。
行expect ".*"
可能没有按照您的想象做:默认的模式匹配样式是 glob ,因此.*
会在文本点后加上任意数字字符。您可能会想到需要添加-re
选项的正则表达式“零个或多个字符”。
但是,强大的期望代码的关键是期望更具体的模式。