Q:利用shell腳本實現ssh自動登錄遠程服務器?
A:expect命令
#!/usr/bin/expect spawn ssh root@172.16.11.99 expect "*password:" send "rootzhang\r" expect "*#" interact
#!/usr/bin/expect //告訴操作系統,此腳本里的代碼用expect這個shell來執行(類似與bash)
shell> expect 腳本 //執行expect腳本
1、使用expect -c的嵌套調用
如果需要在shell腳本中嵌套expect代碼,就要使用expect -c "expect代碼"
expect -c " spawn ssh $user_name@$ip_addr df -P expect { \"*(yes/no)?\" {send \"yes\r\" ; exp_continue} \"*password:\" {send \"$user_pwd\r\" ; exp_continue} #退出 } "
格式:spawn ssh登錄遠程主機 在該遠程主機上要執行的命令(只能執行一條)
注意:在expect -c里面的代碼,雙引號要用\轉義字符。
2、使用here document的嵌套調用
#!/bin/bash echo "123" /usr/bin/expect <<EOF #利用here document的expect代碼嵌套
spawn ssh root@172.16.11.99 expect "*password:" send "rootzhang\r" expect "*#" send "touch zhangjiacai\r" expect "*#" send "exit\r" expect eof #捕獲結束
EOF
expect詳解-- programmed dialogue with interactive programs
是一個工具,是一個用來處理交互的命令。
借助Expect,我們可以將交互過程寫在一個腳本上,使之自動化完成。
形象的說,ssh登錄,ftp登錄等都符合交互的定義。可以根據用戶設定的規則和系統進程進行自動化交互,例如遠程登陸的密碼輸入、自動化的執行遠程命令。
expect中最關鍵的四個命令是spawn、expect、send、interact
spawn:啟動新的進程,后面可接shell命令
expect:從進程接收字符串
send:用於向進程發送字符串 interact:允許用戶交互
1、spawn命令
spawn命令就是用來啟動新的進程的。
spawn后的send和expect命令都是和spawn打開的進程進行交互的。
set timeout 30 //設置超時時間,單位是:秒 spawn ftp 172.16.1.1 //打開新的進程,該進程用戶連接遠程ftp服務器 expect "Name" //進程返回Name時 send "ftp\r" //向進程輸入ftp\r expect "Password:" //進程返回Password:時 send "123456\r" //向進程輸入123456\r expect "ftp> " //進程返回ftp>時 send "mirror xiang\r" //向進程輸入mirror xiang\r #下載xiang文件夾 expect "ftp> " send "exit\r" //向進程輸入exit\r #退出
2、send命令
send命令接收一個字符串參數,並將該參數發送到進程。(有點像here document)
3、expect命令
expect通常是用來等待一個進程的反饋,expect可以接收一個字符串參數,也可以接收正則表達式參數。
和上文的send命令結合,實現簡單的交互式。
模式-動作:
> 單一分支模式語法:
expect "hi" {send "You said hi"} #匹配到hi后,會輸出"you said hi"給進程,作為標准輸入
> 多分支模式語法:
#匹配到hi,hello,bye任意一個字符串時,執行相應的輸出。
expect { "hi" { send "You said hi\n"; exp_continue} "hello" { send "Hello yourself\n"; exp_continue} "bye" { send "That was unexpected\n"} }
4、interact
利用spawn、expect、send自動化完成部分操作。
如果想在適當的時候干預這個過程---就用到了interact(互相影響 互相作用)
比如下載完ftp文件時,仍然可以停留在ftp命令行狀態,以便手動的執行后續命令。interact可以達到這些目的,在自動登錄ftp后,允許用戶交互。
spawn ftp 172.16.1.1 expect "Name" send "ftp\r" expect "Password:" send "123456\r" interact //留在ftp中手動執行后續命令操作
> 執行完成后保持交互狀態,把控制權交給控制台,這個時候就可以手工操作了;
> 如果沒有這一句登錄完成后會退出,而不是留在遠程終端上。
總結:
expect工具在日常的運維中非常有用,可以用在多機器服務重啟、遠程copy、多機器日志查看、ftp文件操作、telnet等多種場景。shell中有些操作會受限於密碼輸入的人工操作,expect工具可以代替人工來完成一些交互性工作。
