一、Linux系統(tǒng)免除交互操作方法
1、EOF多文本輸入
案例:為機器磁盤進(jìn)行分區(qū)并實現(xiàn)掛載,免交互式操作,如何實現(xiàn)?
#!/bin/bash
fdisk /dev/sdb <<EOF
n
p
1
wq
EOF
mkfs.xfs /dev/sdb1 && mkdir -p /data && mount /dev/sdb1 /data
echo '/dev/sdb1 /data xfs defaults 0 2' >> /etc/fstab
# 與 echo -e "n\np" | fdisk /dev/sdb 方式一樣
2、標(biāo)準(zhǔn)輸出和錯誤輸出重定向 “> file 2>&1”
注意:有些命令的交互操作提示是不算在標(biāo)準(zhǔn)輸出和錯誤輸出中的,此時該方法不適用
ssh root@10.11.20.xxx -o StrictHostKeyChecking=no > logfile 2>&1
status_info=$( cat logfile )
case ${status_info} in
*Connection refused*)
echo "正在執(zhí)行ssh連接主機${host}:ssh連接拒絕,請檢查ssh服務(wù)是否開啟!"
;;
*)
echo "ssh連接中"
附:在腳本中如何替代Ctrl + C等關(guān)閉命令的終端窗口?
注意:命令的交互操作提示是不算終端窗口的,此時該方法不適用
例如可以通過以下方式將telnet命令關(guān)閉
sleep 1 | telnet 127.0.0.1 10050
echo -e "\n" | telnet 10.127.0.0.1 10050
echo "" | telnet 127.0.0.1 10050
telnet 127.0.0.1 10050 < /dev/null 代表標(biāo)準(zhǔn)輸入為空
3、Expect工具
一. expect 簡介
-
expect 工具是一個根據(jù)腳本與其他交互式程序進(jìn)行交互。通過在腳本中設(shè)定期望值和響應(yīng)值進(jìn)行交互操作。主要應(yīng)用于執(zhí)行命令和程序時,系統(tǒng)以交互形式要求輸入指定字符串,實現(xiàn)交互通信。
-
解釋型語言提供分支和高級控制結(jié)構(gòu)引導(dǎo)對話。此外,用戶可以在需要時直接進(jìn)行控制和交互,然后將控制權(quán)返回給腳本。
-
簡單來說,expect工具可以控制、處理輸入,輸出流,然后提供自動填寫數(shù)據(jù)等需要用戶交互式輸入的數(shù)據(jù)的地方實現(xiàn)自動化處理。Expect就是為了處理“自動交互”的工具。
二. expect工作原理
spawn啟動指定進(jìn)程—expect獲取指定關(guān)鍵字—send向指定程序發(fā)送指定字符—執(zhí)行完成退出。
三. 基本語法
expect 啟動選項:
-c 執(zhí)行腳本前先執(zhí)行的命令,可多次使用
-d debug模式,可以在運行時輸出一些診斷信息,與在腳本開始處使用exp_internal 1相似。
-D 啟用交換調(diào)式器,可設(shè)一整數(shù)參數(shù)。
-f 從文件讀取命令,僅用于使用#!時。如果文件名為"-",則從stdin讀取(使用"./-"從文件名為-的文件讀取)。
-i 交互式輸入命令,使用"exit"或"EOF"退出輸入狀態(tài)
-- 標(biāo)示選項結(jié)束(如果你需要傳遞與expect選項相似的參數(shù)給腳本時),可放到#!行:#!/usr/bin/expect --
-v 顯示expect版本信息
expect 命令參數(shù):
spawn 交互程序開始,執(zhí)行后面的命令或程序。
set timeout n 設(shè)置超時時間,表示該腳本代碼需在n秒鐘內(nèi)完成,如果超過,則退出。用來防止ssh遠(yuǎn)程主機網(wǎng)絡(luò)不可達(dá)時卡住及在遠(yuǎn)程主機執(zhí)行命令宕住。如果設(shè)置為-1表示不會超時
set 定義變量,也可以使用"set var [xxx]"方式; 命令置換[],[ ]內(nèi)是獨立的TCL指令,使用不同的TCL指令可實現(xiàn)各種獲取變量的效果。
例如:
set CommandList [lindex $argv 3]
#獲取命令列表,分號分隔
set cmds [split $CommandList ";"]
#獲取命令列表長度
set cmds_num [llength $cmds]
$argv expect腳本可以接受bash的外部傳參,可以使用[ lindex $argv n ]n為0表示第一個傳參,為1表示第二個傳參,以此類推
expect 從交互程序進(jìn)程中指定接收信息, 如果匹配成功, 就執(zhí)行send的指令交互;否則等待timeout秒后自動退出expect語句
send 如果匹配到expect接受到的信息,就將send中的指令交互傳遞,執(zhí)行交互動作。結(jié)尾處加上\r表示如果出現(xiàn)異常等待的狀態(tài)可以進(jìn)行核查
exp_continue 表示循環(huán)式匹配,通常匹配之后都會退出語句,但如果有exp_continue則可以繼續(xù)執(zhí)行下面的匹配。
例如:ssh需要先匹配yes/no,再匹配passoword。
yes/no" { send "yes\r"; exp_continue}
"password:" { send "$passwd\r" }
exit 退出expect腳本
expect eof spawn進(jìn)程結(jié)束后會向expect發(fā)送eof,接收到eof代表該進(jìn)程結(jié)束
interact 執(zhí)行完代碼后保持交互狀態(tài),將控制權(quán)交給用戶。沒有該命令執(zhí)行完后自動退出而不是留在遠(yuǎn)程終端上
send_user 用來打印expect腳本中的信息,類似shell里的echo命令
puts 輸出變量(打印字符串,類似于echo)
注釋:puts
在輸出字符串的尾部自動添加換行符而send_user
不會自動添加,除了換行符外,如果在Expect
腳本中使用日志文件,則通過發(fā)送的語句send_user
會將其放入日志文件,而通過發(fā)送的語句puts
則不會。
四、案例介紹
[root@localhost ~]# vim test.sh => 一般將expect腳本的后綴命名為".sh"
#!/usr/bin/expect => expect的解析器,與shell中的#!/bin/bash類似
set timeout n => 設(shè)置超時時間n秒,表示下面的代碼需在n秒鐘內(nèi)完成(-1代表永不超時),如果超過,則退出。用來防止ssh遠(yuǎn)程主機網(wǎng)絡(luò)不可達(dá)時卡住及在遠(yuǎn)程主機執(zhí)行命令宕住
set name "12345" => set設(shè)置變量,name的值為123456
spawn command1 command2.. => 執(zhí)行命令,也可以將變量作為命令輸入
expect{ => 接受執(zhí)行命令返回的信息
"accept1" {send "instruction1\r"; exp_continue} => 匹配到accest1,發(fā)送instruction1 指令并且\r 回車執(zhí)行
"accept2" {send "instruction2\r"; exp_continue} => 匹配到accest2,發(fā)送instruction2 指令并且\r 回車執(zhí)行,exp_continue表示循環(huán)匹配
"accept3" {send "\r"; exp_continue} => 匹配到accept3表示直接回車執(zhí)行
"accept4" {send "$name\r"} => 匹配到accept4,將變量值作為指令,并且回車執(zhí)行
}
expect eof =>結(jié)束這個進(jìn)程
二、SSH批量修改主機密碼腳本實現(xiàn)
shell腳本使用expect自動化交互工具完成密碼修改:文章來源:http://www.zghlxwxcb.cn/news/detail-715347.html
cat change_password.sh
#!/bin/bash
host_list=(127.0.0.1 127.0.0.2)
logfile=/tmp/change_password.log
old_pawd="password1"
new_pawd="password2"
function change_password(){ #case函數(shù)匹配條件中可以使用某些簡單的正則匹配字符(需測試),特殊字符使用\轉(zhuǎn)義
case ${status_info} in
*"Connection refused"*)
echo "ssh端口不通,請檢查ssh服務(wù)是否開啟!"
;;
*)
echo "ssh端口訪問正常,開始執(zhí)行expect自動化交互操作!"
/usr/bin/expect ./use_ssh.sh ${host} ${old_pawd} ${new_pawd}
esac
}
for host in ${host_list[@]}
do
# "< /dev/null"代表標(biāo)準(zhǔn)輸入為空,作用關(guān)閉終端窗口
$( telnet ${host} 22 < /dev/null > ${logfile} 2>&1 )
status_info=$( cat ${logfile} )
change_password
done
expect自動化交互腳本文章來源地址http://www.zghlxwxcb.cn/news/detail-715347.html
#!/usr/bin/expect
#set timeout 30
#定義變量
set HostIP [lindex $argv 0]
set old_pawd [lindex $argv 1]
set new_pawd [lindex $argv 2]
set Command "passwd root"
# puts "舊密碼為:${old_pawd},新的為:${new_pawd}";
#執(zhí)行ssh命令,-o參數(shù)忽略第一次的yes/no選擇
spawn ssh -l root ${HostIP} -o StrictHostKeyChecking=no
expect {
# 第一次連接輸入密碼
"Password:" {
send "${old_pawd}\r";
exp_continue
}
# 輸入密碼錯誤,會再次提示
"*Password:*" {
send_user " 主機${HostIP}:登錄密碼錯誤,請檢查登錄密碼!";
expect eof
exit 2
}
# 登陸成功,命令行界面,修改密碼
"#" {
send "${Command}\r";
}
"Enter new password:" {
send_user "輸入的新密碼為:${new_pawd}"
send "${new_pawd}\r";
}
"Re-type new password:" {
send_user "再次輸入新密碼:${new_pawd}"
send "${new_pawd}\r";
}
"passwd: password updated successfully" {
send_user " 主機${HostIP}:修改密碼成功!";
send "exit\r"
}
}
sleep 1
send "exit\r"
expect eof
exit
到了這里,關(guān)于“Linux免除系統(tǒng)交互操作方法、expect自動化交互工具” 及 “SSH批量修改主機密碼腳本”的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!