中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

shell編程之Expect免交互

發布時間:2020-05-27 15:42:54 來源:網絡 閱讀:420 作者:wx5d8a17c45cb5b 欄目:系統運維

shell編程之Expect免交互

一、前言

? shell腳本存在的核心意義就在于基于shell命令簡化甚至省略可避免的人工操作,通過各種控制流程結構以及正則表達式等方法,逐步實現自動化操作的整個過程,由此也可見,shell并沒有面向對象的思想,類似C語言,畢竟C語言是操作系統或者說是內核的核心語言。

? 所以,語言并無優劣之分,只是每個人使用的習慣與方式不同,換句話說,難易的不是語言,而是思想與突如其來的靈感。

二、Expect概述與安裝

Expect概述

? Expect是建立在TCL基礎上的一個工具,Expect是用來進行自動化控制和測試的工具。主要解決shell腳本中不可交互的問題。對于大規模的Linux運維很有幫助。

? 在Linux運維和開發中,我們經常需要遠程登錄服務器進行操作,登錄的過程是一個交互過程,需要輸入yes/no password等信息。為了模擬這種輸入,可以使用Expect腳本。

Expect的安裝:yum install -y expect

三、基本命令

  1. send:向進程發送字符串,用于模擬用戶的輸入,但不支持換行 一般需要加上 \r

  2. expect:內部命令

    ? 判斷上次輸出結果里是否包含指定的字符串,有則返回,反之就等待超時時間后返回。

    ? 只能捕捉由spawn啟動的進程的輸出。

  3. spawn:啟動進程,并跟蹤后續交互信息。

  4. interact:執行完成后保持交互狀態,把控制權交給控制臺。

Timeout:指定超時時間,過期則繼續執行后續指令

  • 單位是s
  • timeout -1為永不超時
  • 默認情況下timeout 是10s

exp_continue——允許expect繼續向下執行指令(比較關鍵,多次交互)

send_user——回顯命令,相當于echo

四、expect語法

expect [選項] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
選項
-c:從命令行執行expect腳本,默認expect是交互地執行的
示例:expect -c 'expect "\n" {send "pressed enter\n"}
-d:可以輸出輸出調試信息
示例:expect -d ssh.exp

expect最常用的語法(tcl語言:模式-動作)
單一分支模式語法:
expect “hi” {send “You said hi\n"} 匹配到hi后,會輸出“you said hi”,并換行,也可以使用\r
多分支模式語法:
expect "hi" { send "You said hi\n" } \ "hehe" { send “Hehe yourself\n" } \ "bye" { send “Good bye\n" }
匹配hi,hello,bye任意字符串時,執行相應輸出.等同如下:
expect { "hi" { send "You said hi\n"} "hehe" { send "Hehe yourself\n"} "bye" { send “Good bye\n"} }

五、實例:

1)ssh免交互遠程登錄

[root@lokott ~]# yum install -y expect
已加載插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
...//省略部分
[root@lokott shell]# cat a.sh 
#使用which expect查看其位置
#!/usr/bin/expect
#設置超時時間
    set timeout 20
    log_file test.log
    log_user 1
#變量定義
    set hostname [lindex $argv 0]
    set passwd [lindex $argv 1]
#啟動進程,spawn監控
    spawn ssh root@$hostname
#匹配條件
    expect {
        "(yes/no)"
#exp_continue表示繼續向下匹配
        {send "yes\r";exp_continue}  
        "*password"
        {send "$passwd\r"}
}
#轉交權限給控制臺
interact 

[root@lokott shell]# ./a.sh 192.168.68.129 123456   //第一次登錄
spawn ssh root@192.168.68.129
The authenticity of host '192.168.68.129 (192.168.68.129)' can't be established.
ECDSA key fingerprint is SHA256:k/6W9M/dgxVrbMgSx9nIFPGfVgUfLMoIb27ys9ZF+LM.
ECDSA key fingerprint is MD5:26:dd:06:b3:32:bd:d6:a3:2f:7c:66:7d:b9:c0:4b:c4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.68.129' (ECDSA) to the list of known hosts.
root@192.168.68.129's password: 
Last login: Wed Dec  4 10:24:33 2019 from 192.168.68.1
[root@localhost ~]# exit
登出
Connection to 192.168.68.129 closed.
[root@lokott shell]# ./a.sh 192.168.68.129 123456   //第二次登錄上一次登錄需要的秘鑰已經保存
spawn ssh root@192.168.68.129
root@192.168.68.129's password: 
Last login: Wed Dec  4 10:29:42 2019 from 192.168.68.130
[root@localhost ~]# exit
登出
Connection to 192.168.68.129 closed.

上述演示的是直接使用expect腳本實現ssh遠程登錄的操作過程,而expect腳本也可以被嵌入到普通的腳本文件中,下面給出具體演示:

[root@lokott shell]# cat b.sh 
#嵌入expect執行實現免交互登錄
#!/bin/bash
#定義普通變量,在該shell腳本中始終有效
hostname=$1
passwd=$2
#嵌入寫入expect腳本內容??實現免交互的具體內容
/usr/bin/expect<<-EOF
spawn ssh root@$hostname
expect {
    "(yes/no)"
    {send "yes\r";exp_continue}
    "*password"
    {send "$passwd\r";}
}
#下兩行是為了返回本地控制臺的操作演示
expect "*]#"
send "exit\r"
expect eof
EOF
#注意EOF的前后都不可以有空格!!!
[root@lokott shell]# ./b.sh 192.168.68.129 123456
spawn ssh root@192.168.68.129
root@192.168.68.129's password: 
Last login: Wed Dec  4 12:22:23 2019 from 192.168.68.130
[root@localhost ~]# exit
登出
Connection to 192.168.68.129 closed.

推薦使用這種方式,因為在實際使用中一般都是在普通腳本中使用expect的,所有嵌入寫入比較方便,比較常用!

直接使用expect免交互的完整腳本如下,有興趣可以試著改為嵌入寫入的代碼:

[root@lokott shell]# cat ssh.sh 
#!/usr/bin/expect
set timeout 5
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh root@$hostname
expect {
"No route to host" exit
"Invalid argument" exit
"Connection refused" exit
"Name or service not known" exit
"to continue" {send "yes\r";exp_continue}
"password:" {send "$password\r"}
}
interact
exit
[root@lokott shell]# ./ssh.sh 192.168.68.133 123456  //服務器非在線
spawn ssh root@192.168.68.133
ssh: connect to host 192.168.68.133 port 22: No route to host
[root@lokott shell]# ./ssh.sh  123456    //參數輸入錯誤
spawn ssh root@123456
ssh: connect to host 123456 port 22: Invalid argument
[root@lokott shell]# ./ssh.sh 192.168.68.129 123456   //正常登錄
spawn ssh root@192.168.68.129
root@192.168.68.129's password: 
Last login: Wed Dec  4 15:20:51 2019 from 192.168.68.130
[root@localhost ~]# 

2)添加用戶與用戶密碼的免交互操作過程

[root@lokott shell]# cat c.sh 
#!/bin/bash
username=$1
password=$2
useradd $1
[ $? -eq 0 ]&&echo ||exit 1
/usr/bin/expect<<-EOF
spawn passwd ${username}
expect {
    "密碼:"
    {send  "${password}\r";exp_continue}

    "密碼:"
    {send  "${password}\r";}

}
EOF

tail -1 /etc/shadow|awk -F: '{print $1,$2}'
userdel -r $1
#執行結果如下
[root@lokott shell]# ./c.sh zhazhahui 123456

spawn passwd zhazhahui
更改用戶 zhazhahui 的密碼 。
新的 密碼:
無效的密碼: 密碼少于 8 個字符
重新輸入新的 密碼:
passwd:所有的身份驗證令牌已經成功更新。
zhazhahui $6$k.MdzCd3$XMUGf5XQV4sE5RJqcwdEoOkd8UVgWtwcguzi6Md5yXcagYvgyE8GmCjzjxkEB5rXR.IRG9j49c36amzkDIe5l1

六、總結

? 本文主要介紹了expect實現免交互的作用以及結合實際案例講解其兩種使用方式(直接和嵌入)的具體操作過程。

? 過程主要分為:基本變量定義(timeout最好最先設置)——spawn啟動跟蹤——expect匹配——interact交付控制權(沒有會退出)或者expect eof 結束expect匹配。

? 務必結合上述的案例自己多使用體會理解!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

太白县| 玛纳斯县| 班玛县| 鹤岗市| 莱芜市| 沂源县| 新昌县| 天镇县| 嘉义市| 元阳县| 临安市| 清水县| 顺昌县| 潮安县| 克什克腾旗| 会东县| 额济纳旗| 合山市| 双江| 崇明县| 获嘉县| 南充市| 清远市| 五指山市| 阜阳市| 浦东新区| 武夷山市| 云霄县| 麻城市| 赣榆县| 漳州市| 信阳市| 集安市| 黄骅市| 兴仁县| 郴州市| 萍乡市| 曲水县| 邵阳市| 房山区| 郸城县|