Shell編程之Expect免交互

Shell編程之Expect免交互

Expect概述

expect是建立在tcl語言基礎上的一個工具,它可以讓一些需要交互的任務自動化地完成。相當於模擬了用戶和命令行的交互操作。
一個常用的場景就是批量配置集羣無祕鑰登錄。如果集羣的機器數量很多,手動一臺一臺地去每臺機子去配置無密鑰是非常糟糕的事情。使用expect功能,可以遠程登錄機器,並通過交互方式進行無祕鑰登錄。

Expect安裝

掛載光盤
製作本地yum源
執行安裝命令:yum install expect -y

Expect基本命令

send:向進程發送字符串,用於模擬用戶的輸出
expect:expect的一個內部命令,判斷上次輸出結果裏是否包含指定的字符串,如果有則立即返回,否則就等待超時時間後返回。
spawn:啓動進程,並跟蹤後續交互信息
interact:執行完後保持交互狀態,把控制權交給控制檯
EOF:結束
Timeout:指定超時時間,過期則繼續執行後續指令
​單位是秒
​timeout -1 爲永不超時
​默認情況下,timeout是10秒
exp_continue
允許expect繼續向下執行命令
send_user
回顯命令,相當於echo
$argv參數數組
Expect腳本可以接受從bash傳遞的參數,可以使用[lindex $argv n]獲得,n從0開始,分別表示第一個,第二個,第三個。。。。參數
Expect腳本必須以interact或者expect eof結束,執行自動化任務通常expect eof就夠了
expect eof是在等待結束標誌。由spwan啓動的命令在結束時會產生一個eof標記,expect eof即在等待這個標記。

Expect執行方式

直接執行

ssh免交互遠程連接

#!/usr/bin/expect
#超時時間
set timeout 20
log_file test.log
log_user 1
#參數傳入
set hostname [lindex $argv 0]
set password [lindex $argv 1]
#追蹤命令
spawn ssh root@$hostname
#捕捉信息並且匹配,免交互執行
expect {
        "(yes/no)"
        {send "yes\r";exp_continue}
        "*password"
        {send "$password\r"}
}
#控制權交給控制檯執行
interact

腳本執行結果

[root@localhost opt]# chmod +x a.sh 
[root@localhost opt]# ./a.sh 192.168.131.129 123123 
spawn ssh [email protected]
[email protected]'s password: 
Last login: Thu Oct 10 18:56:11 2019 from 192.168.131.133
[root@localhost ~]#

嵌入執行

ssh免交互遠程連接

#!/bin/bash
   hostname=$1
   password=$2
   /usr/bin/expect<<-EOF
   spawn ssh root@${hostname}
   expect {
          "(yes/no)"
          {send "yes\r";exp_continue}
          "*password"
          {send "$password\r"}
  }
  expect "*]#"
  send "exit\r"
  expect eof
EOF

腳本執行結果

[root@localhost opt]# chmod +x b.sh 
[root@localhost opt]# ./b.sh 192.168.131.129 123123 
spawn ssh [email protected]
[email protected]'s password: 
Last login: Thu Oct 10 18:56:02 2019 from 192.168.131.133
[root@localhost ~]# exit
登出
Connection to 192.168.131.129 closed.
[root@localhost opt]#

Expect案例

創建用戶tom,密碼tom123

#!/bin/bash
hostname=$1
password=$2
useradd $hostname
expect <<-EOF
spawn passwd $hostname
expect "新的*"
send "$password\r"
expect "重新輸入*"
send "$password\r"
expect eof;
EOF
[root@localhost opt]# chmod +x c.sh 
[root@localhost opt]# ./c.sh tom tom123
spawn passwd tom
更改用戶 tom 的密碼 。
新的 密碼:
無效的密碼: 密碼少於 7 個字符
重新輸入新的 密碼:
passwd:所有的身份驗證令牌已經成功更新。
[root@localhost opt]# 

SSH遠程登錄腳本健壯版
在ssh遠程登錄無法連接到時,不會輸出報錯信息。

#!/usr/bin/expect
set timeout 20 //超時時間
log_file test.log
log_user 1
set hostname [lindex $argv 0] //參數傳入
set password [lindex $argv 1]
spawn ssh root@$hostname //追蹤命令
expect { //捕捉信息並且匹配,免交互執行
"Connection refused" exit
"service not known" exit
"(yes/no)"
{send "yes\r";exp_continue}
"*password"
{send "$password\r"}
}
interact //控制權交給控制檯執行
exit

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章