linux腳本中有不少場景是進行遠程操做的,例如遠程登陸ssh、遠程複製scp、文件傳輸sftp等。這些命令中都會涉及到安全密碼的輸入,正常使用命令時是須要人工手動輸入密碼並接受安全驗證的。爲了實現自動化遠程操做,咱們能夠借用expect的功能。linux
expect的核心是spawn、expect、send、set。安全
expect
等待命令提示信息的出現,也就是捕捉用戶輸入的提示:send
發送須要交互的值,替代了用戶手動輸入內容set
設置變量值interact
執行完成後保持交互狀態,把控制權交給控制檯,這個時候就能夠手工操做了。若是沒有這一句登陸完成後會退出,而不是留在遠程終端上。expect eof
這個必定要加,與spawn對應表示捕獲終端輸出信息終止,相似於if....endif服務器
expect腳本必須以interact或expect eof結束,執行自動化任務一般expect eof就夠了。ssh
set timeout -1
set timeout 300
expect使用的是tcl語法spa
cmd arg arg arg
$foo
[cmd arg]
"some stuff"
{some stuff}
login.exp專用於遠程登陸,快捷使用方式: login.exp "exclude" "${remote_ip}" "${remote_user}" "${remote_passwd}" "${remote_command}"
code
#!/usr/bin/expect -f ########################################################## # 經過SSH登錄和執行命令 #參數:1.Use_Type [check/execute] # 2.SSHServerIp # 3.SSHUser # 4.SSHPassword # 5.CommandList [多個命令間以;間隔] #返回值: # 0 成功 # 1 參數個數不正確 # 2 SSH 服務器服務沒有打開 # 3 SSH 用戶密碼不正確 # 4 鏈接SSH服務器超時 ########################################################## proc usage {} { regsub ".*/" $::argv0 "" name send_user "Usage:\n" send_user " $name Use_Type SSHServerIp SSHUser SSHPassword CommandList\n" exit 1 } ## 判斷參數個數 if {[llength $argv] != 5} { usage } #設置變量值 set Use_Type [lindex $argv 0] set SSHServerIp [lindex $argv 1] set SSHUser [lindex $argv 2] set SSHPassword [lindex $argv 3] set CommandList [lindex $argv 4] #spawn ping ${SSHServerIp} -w 5 #expect { # -nocase -re "100% packet loss" { # send_error "Ping ${SSHServerIp} is unreachable, Please check the IP address.\n" # exit 1 # } #} set timeout 360 set resssh 0 #定義變量標記ssh鏈接時是否輸入yes確認 set inputYes 0 set ok_string LOGIN_SUCCESS if {$Use_Type=="check"} { #激活ssh鏈接,若是要須要輸入yes確認,輸入yes,設置inputYes爲1,不然輸入ssh密碼 spawn ssh ${SSHUser}@${SSHServerIp} "echo $ok_string" } else { spawn ssh ${SSHUser}@${SSHServerIp} "$CommandList" } expect { -nocase -re "yes/no" { send -- "yes\n" set inputYes 1 } -nocase -re "assword: " { send -- "${SSHPassword}\n" set resssh 1 } #-nocase -re "Last login: " { # send -- "${CommandList}\n" #} $ok_string {} -nocase -re "Connection refused" { send_error "SSH services at ${SSHServerIp} is not active.\n" exit 2 } timeout { send_error "Connect to SSH server ${SSHUser}@${SSHServerIp} timeout(10s).\n" exit 4 } } #若是輸入了yes確認,輸入ssh密碼 if {$inputYes==1} { expect { -nocase -re "assword: " { send -- "${SSHPassword}\n" set resssh 1 } } } #若是出現try again或者password:提示,說明輸入的用戶密碼錯誤,直接退出。 if {$resssh==1} { expect { -nocase -re "try again" { send_error "SSH user:${SSHUser} passwd error.\n" exit 3 } -nocase -re "assword:" { send_error "SSH user:${SSHUser} passwd error.\n" exit 3 } eof {} } } send_error -- "$expect_out(buffer)" #-nocase -re "No such user" { # send_error "No such user.\n" # exit 5 # } #exit