expect 內(nèi)部命令
語法結(jié)構(gòu)
spawn shell 命令程序
expect "捕獲到shell 命令程序執(zhí)行之后輸出的字符串"
send "發(fā)送給 shell 命令程序的字符串"
在命令行直接輸入 expect 可以進(jìn)入 expect 程序的解釋器終端
[root@e5ac44e88027 ~]# expect
expect1.1> spawn echo "hello" # 發(fā)送一條 shell 命令除盏, 這里是指 echo "hello"
spawn echo hello
1490
expect1.2> expect "hello" # 捕獲這個字符串,只要包含這個字符串就可以
hello
expect1.3> send "yes\n" # 發(fā)送一個字符串
expect1.4> expect off # 結(jié)束這次捕獲
yes
expect1.5>
在腳本中使用
# 開始 expect 解釋器程序
/usr/bin/expect<<EOF
# 設(shè)置捕獲字符串后,期待回復(fù)的超時時間
set timeout 30
spawn ssh-keygen
# 開始進(jìn)連續(xù)捕獲
expect {
".ssh/id_rsa)" { send "\n"; exp_continue }
"Overwrite (y/n)?" { send "y\n"; exp_continue }
"no passphrase):" { send "\n"; exp_continue }
"again:" { send "\n"; exp_continue }
}
# 結(jié)束 expect 解釋器程序
EOF
".ssh/id_rsa)" { send "\n"; exp_continue }
意思是 捕獲到字符串 ".ssh/id_rsa)" 后 發(fā)送字符串 "\n" 就是相當(dāng)于按下回車鍵
exp_continue 意思是繼續(xù)進(jìn)行捕獲巴元,不退出 expect 程序
實戰(zhàn)案例
# 寫個用于自動生成密鑰對的函數(shù)
auto_keygen (){
/usr/bin/expect<<EOF
set timeout 30
spawn ssh-keygen
expect {
".ssh/id_rsa)" { send "\n"; exp_continue }
"Overwrite (y/n)?" { send "y\n"; exp_continue }
"no passphrase):" { send "\n"; exp_continue }
"again:" { send "\n"; exp_continue }
}
EOF
}
# 寫個自動免密登錄的函數(shù)
send_key () {
pwd=upsa
/usr/bin/expect <<EOF
set timeout 30
# 發(fā)送公鑰給對方服務(wù)器
spawn ssh-copy-id root@$1
expect {
"yes/no" { send "yes\n"; exp_continue }
"password:" { send "${pwd}\n"} }
expect eof
EOF
}
# 定義一個變量,其值是當(dāng)前用戶的公鑰文件
pub_key_file=$HOME/.ssh/id_rsa.pub
# 假如公鑰文件不存在驮宴,說明需要創(chuàng)建密鑰對
if [ ! -f ${pub_key_file} ];then
auto_keygen
fi
# 循環(huán)一個存放 ip 地址的文件逮刨,并且把每個 IP地址傳遞給 函數(shù)
for ip in $(cat ./ips.txt)
do
send_key $ip
done
keygen (){
/usr/bin/expect<<EOF
spawn ssh-keygen
expect {
"(/root/.ssh/id_rsa):" { send "\n"; exp_continue }
"Overwrite (y/n)?" { send "y\n"; exp_continue }
"(empty for no passphrase):" { send "\n"; exp_continue }
"passphrase again:" { send "\n" exp_continue }
}
EOF
}
copyid (){
passwd=密碼
/usr/bin/expect<<EOF
spawn ssh-copy-id root@$ip
expect {
"continue connecting (yes/no)?" {send "yes\n" exp_continue }
"password:" { send "$passwd\n" exp_continue }
}
EOF
}
idfile=$HOME/.ssh/id_rsa.pub
if [ -f $idfile ];then
exit
else
keygen
fi
for ip in 10.3.134.{2..254} #多主機(jī)進(jìn)行交互免密登陸
do
copyid $ip
done