我正在尝试使用 Expect 编写一个脚本来监视多个服务器;连接将通过 ssh 使用密码进行。
我的基本循环是自我失败的,我不确定 Expect TCL 语言是否接受 Linux for 循环语法。
代码:
#!/usr/bin/expect -f
server_list="/tmp/DR.txt"
for HOST in $(cat $server_list) ; do
spawn ssh -q $HOST
expect "assword:"
send "Abcd@123\r"
interact
echo ' '
echo "====For space utilization details for server $HOST===" >/tmp/space_utilization.log
Df -kh >> /tmp/space_utilization.log
echo ' '
done
该文件/tmp/DR.txt
包含 100 个服务器名称的列表,如下所示:
hzavks01
dzavks20
dzavks03
uzavks05
acavks30
我得到的错误是:
[root@dzavks20 tmp]# ./expect.sh
invalid command name "server_list=/tmp/DR"
while executing
"server_list=/tmp/DR"
(file "./expect.sh" line 2)
答案1
一定要用expect吗?您能否拥有一个简单的 bash shell,通过 ssh 远程运行 df 命令并将信息收集到单个文件中?
如果配置文件中从调用服务器到所有服务器的 ssh 密钥设置正确,则无需输入任何密码。以下循环将从所有服务器收集 df 输出
while read -r h; do
echo "=== Space utilization for ${h} ==="
ssh "$h" df -kh
echo ""
done </tmp/DR.txt >/tmp/space_utilization.log
答案2
如果可以的话,请使用 ssh 私钥身份验证:一旦设置完毕,您就无需考虑它。此外,您不需要以纯文本形式存储密码。
另外,代码是一个很多更复杂:
#!/usr/bin/expect -f
set server_list /tmp/DR.txt
set fh_hosts [open $server_list r]
# truncate the log file
set log_file /tmp/space_utilization.log
close [open $log_file w]
set pass "Abcd@123"
set prompt_re {\$ $}
while {[gets $fh host] != -1} {
spawn ssh -q $host
expect "assword:"
send "$pass\r"
expect -re $prompt
set cmd "df -kh"
send "$cmd\r"
expect -re "$cmd\r\n(.*)\r\n$prompt"
log_file $log_file
send_log "\n"
send_log "====Space utilization for server $host at [timestamp -format +"%Y-%m-%d %T"]===\n"
send_log -- $expect_out(1,string)
send_log "\n\n"
log_file
send "exit\r"
expect eof
}
close $fh_hosts