有时在使用expect脚本进行ssh登录到远程主机执行命令时需要保存回显为日志文件,这里总结三种方式
1. $expect_out(buffer)
这种方式需要注意不能在shell嵌套expect的情况下使用,因为在这种情况下expect脚本中的$xx
变量会被解析成shell部分传入的参数,无法起到原本在expect脚本下的作用。
其次,$expect_out(buffer)
需要和send
内容在两个不同的expect循环中出现。
#!/bin/expect
set user "root"
set host "10.25.103.2"
set loginpass "eve"
spawn ssh -p 23 $user@$host
set timeout 30
set ofile "info_$host" # 在本地创建日志
set output [open $ofile "w"] # 打开日志,准备写入
expect {
-re "Are you sure you want to continue connecting (yes/no)?"{
send "yes\r"
}
-re "password:" {
send "${loginpass}\r"
}
-re "Permission denied, please try again." {
exit
}
}
expect {
"#" {
send {
cat /proc/net/dev}
send "\r"
}
}
expect {
"#" {
set outcome $expect_out(buffer) # 获取回显
send "\r"
puts $output $outcome # 将回显写入日志
unset expect_out(buffer) # 清空回显缓存
}
}
close $output # 关闭日志文件
expect {
-re $cmd_prompt {
send "exit \r"
}
}
interact
2. 在/usr/bin/expect<<-EOF中创建日志文件(终端有回显)
主要写法,就是在/usr/bin/expect<<-EOF下面添加一行:
/usr/bin/expect<<-EOF
log_file ssh.log
这样在程序执行完成之后本地就会出现一个ssh.log的日志文件,同时终端会有回显
3. 在/usr/bin/expect <<EOF中创建日志文件(终端无回显)
这种方式就是直接把回显写入日志文件,这样本地终端就不会有回显了,干净了许多,方法就是利用输出重定向:
/usr/bin/expect <<EOF > ${log_file}
同时在expect脚本之后我们可以对回显结果进行一个判断,查看是否有报错:
/usr/bin/expect <<EOF > ${log_file}
set timeout -1
spawn ssh -p 23 ${user_name}@${host_ip}
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" {
send "${user_password}\n"}
}
"*assword:"
{
send "${user_password}\n"
}
}
sleep 1
send "${cmd}\n"
send "exit\n"
expect eof
EOF
cat ${log_file} | grep -iE "Permission denied|failed" >/dev/null
if [ $? -eq 0 ];then
echo "Script execute failed!"
return 1
fi