欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python pexpect模塊及shell腳本except原理解析

 更新時(shí)間:2020年08月03日 08:33:14   作者:羊草  
這篇文章主要介紹了Python pexpect模塊及shell腳本except原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

expect腳本

expect是什么

expect是一個(gè)免費(fèi)的編程工具,用來實(shí)現(xiàn)自動(dòng)的交互式任務(wù),而無需人為干預(yù)。說白了,expect就是一套用來實(shí)現(xiàn)自動(dòng)交互功能的軟件。

在實(shí)際工作中,我們運(yùn)行命令、腳本或程序時(shí),這些命令、腳本或程序都需要從終端輸入某些繼續(xù)運(yùn)行的指令,而這些輸入都需要人為的手工進(jìn)行。而利用expect,則可以根據(jù)程序的提示,模擬標(biāo)準(zhǔn)輸入提供給程序,從而實(shí)現(xiàn)自動(dòng)化交互執(zhí)行

由于在linux中的一些命令不太適合于腳本的自動(dòng)化運(yùn)行,比如fdisk,telnet,ftp連接下載等,所以必須使用except來解決交換問題。

except基礎(chǔ)

包含以下四個(gè)命令

命令 作用
send 用于向進(jìn)程發(fā)送字符串
except 從進(jìn)程接收字符串
spwan 啟動(dòng)新進(jìn)程
interact 允許用戶交互

  • send命令接收一個(gè)字符串參數(shù),并將該參數(shù)發(fā)送到進(jìn)程。
  • expect命令和send命令相反,expect通常用來等待一個(gè)進(jìn)程的反饋,我們根據(jù)進(jìn)程的反饋,再發(fā)送對(duì)應(yīng)的交互命令。
  • spawn命令用來啟動(dòng)新的進(jìn)程,spawn后的send和expect命令都是和使用spawn打開的進(jìn)程進(jìn)行交互。
  • interact命令用的其實(shí)不是很多,一般情況下使用spawn、send和expect命令就可以很好的完成我們的任務(wù);但在一些特殊場(chǎng)合下還是需要使用interact命令的,interact命令主要用于退出自動(dòng)化,進(jìn)入人工交互。比如我們使用spawn、send和expect命令完成了ftp登陸主機(jī),執(zhí)行下載文件任務(wù),但是我們希望在文件下載結(jié)束以后,仍然可以停留在ftp命令行狀態(tài),以便手動(dòng)的執(zhí)行后續(xù)命令,此時(shí)使用interact命令就可以很好的完成這個(gè)任務(wù)。

代碼舉例

#!/usr/bin/expect

set timeout 30
set host "101.200.241.109"
set username "root"
set password "123456"

spawn ssh $username@$host
expect "*password*" {send "$password\r"}
interact

這是一段非常簡(jiǎn)單代碼,演示了基本用法

#!/usr/bin/expect:使用expect來解釋該腳本;

set timeout 30:設(shè)置超時(shí)時(shí)間,單位為秒,默認(rèn)情況下是10秒;

set host "101.200.241.109":設(shè)置變量;

spawn ssh $username@$host:spawn是進(jìn)入expect環(huán)境后才可以執(zhí)行的expect內(nèi)部命令,如果沒有裝expect或者直接在默認(rèn)的SHELL下執(zhí)行是找不到spawn命令的。它主要的功能是給ssh運(yùn)行進(jìn)程加個(gè)殼,用來傳遞交互指令;

expect "password":這里的expect也是expect的一個(gè)內(nèi)部命令,這個(gè)命令的意思是判斷上次輸出結(jié)果里是否包含“password”的字符串,如果有則立即返回;否則就等待一段時(shí)間后返回,這里等待時(shí)長就是前面設(shè)置的30秒;

send "$password\r":當(dāng)匹配到對(duì)應(yīng)的輸出結(jié)果時(shí),就發(fā)送密碼到打開的ssh進(jìn)程,執(zhí)行交互動(dòng)作;

interact:執(zhí)行完成后保持交互狀態(tài),把控制權(quán)交給控制臺(tái),這個(gè)時(shí)候就可以手工操作了。如果沒有這一句登錄完成后會(huì)退出,而不是留在遠(yuǎn)程終端上。

這就是對(duì)上述這段簡(jiǎn)單簡(jiǎn)單腳本的分析,在上述的示例中,涉及到expect中一個(gè)非常重要的概念——模式-動(dòng)作;即上述expect "password" {send "$password\r"}這句代碼表達(dá)出來的含義。

模式-動(dòng)作

結(jié)合著expect "password" {send "$password\r"}這句代碼來說說“模式-動(dòng)作”。簡(jiǎn)單的說就是匹配到一個(gè)模式,就執(zhí)行對(duì)應(yīng)的動(dòng)作;匹配到password字符串,就輸入密碼

如下所示:

expect {
  "password" {
    send "$password\r"
    exp_continue
  }
  eof
  {
    send "eof"
  }
}

其中exp_continue表示循環(huán)式匹配,通常匹配之后都會(huì)退出語句,但如果有exp_continue則可以不斷循環(huán)匹配,輸入多條命令,簡(jiǎn)化寫法。

傳參

很多時(shí)候,我們需要傳遞參數(shù)到腳本中,現(xiàn)在通過下面這段代碼來看看如何在expect中使用參數(shù):

#!/usr/bin/expect

if {$argc < 3} {
  puts "Usage:cmd <host> <username> <password>"
  exit 1
}

set timeout -1
set host [lindex $argv 0] 
set username [lindex $argv 1]
set password [lindex $argv 2]

spawn ssh $username@$host
expect "*password*" {send "$password\r"}
interact

在expect中,\$argc表示參數(shù)個(gè)數(shù),而參數(shù)值存放在$argv中,比如取第一個(gè)參數(shù)就是[lindex $argv 0],以此類推。

FTP下載expect腳本

使用yum安裝expect

yum install expect

按照如下編寫expect腳本

#!/usr/bin/expect -f 
set ip [lindex $argv 0]                           #腳本的第一個(gè)參數(shù),遠(yuǎn)程主機(jī)的IP地址
set file [lindex $argv 1]                          #腳本的第二個(gè)參數(shù),指定下載的文件名
set timeout 10                                #設(shè)置超時(shí)時(shí)間10秒
spawn ftp $ip                                 #運(yùn)行ftp $ip命令
expect "Name*"                               #如果出現(xiàn)Name字符
send "anonymous \r"                           #則輸入anoymous(匿名用戶)并回車
expect "Password:*"                           #如果出現(xiàn)Password字符
send "\r"                                     #則僅輸入回車
expect "ftp>*"                                 #如果出現(xiàn)ftp>字符
send "get $file\r"                               #則發(fā)送get $file命令
expect {
  "*Failed*" { send_user " Download failed\r";send "quit\r"}  #如果返回的字符串有Failed,則說明下載失敗,send_user回顯信息 Download failed 
  "*send*" { send_user " Download ok\r";send "quit\r"} #如果返回的字符串有send,則說明下載失敗,send_user回顯信息 Download ok
  }
expect eof  #結(jié)束循環(huán)匹配

給腳本加上可執(zhí)行權(quán)限chmod +x expect_ftp_auto.exp

pexpect模塊

pexpect可以理解為linux下的expect的python封裝,通過pexpect可以實(shí)現(xiàn)ssh,ftp,passwd,telnet等命令的進(jìn)行自動(dòng)交互

安裝pip install pexpect

簡(jiǎn)單實(shí)現(xiàn)ssh自動(dòng)登錄的示例如下:

import pexpect
child = pexpect.spwan('scp foo user#expample.com:.')  #spwan啟動(dòng)scp程序
child.expect('Password:')          #expect方法等待子程序產(chǎn)生的輸出,判斷是否匹配定義的字符串
                                            #‘Password:'
child.sendline(mypassword)       #匹配后則發(fā)送密碼進(jìn)行回應(yīng)

核心組件

spawn類

spawn是pexpect的主要入口,功能是啟動(dòng)和控制子應(yīng)用程序,以下是它的構(gòu)造函數(shù)

class pexpect.spwan(command,args=[],timeout=30,maxread=2000,searchwindowsize=None,logfile=None,cwd=None,env=None,ignore_sighup=True)

其中,command參數(shù)可以是任意已知的系統(tǒng)命令,比如

child=pexpect.spawn('user/bin/ftp')

當(dāng)子程序需要參數(shù)的時(shí)候,還可以使用python列表來代替參數(shù),如

child = pexpect.spwan('user/bin/ssh user@example.com')

參數(shù)timeout為等待結(jié)果的超時(shí)時(shí)間,maxread為從終端控制臺(tái)一次讀取的最大字節(jié)數(shù),searchwindowsize參數(shù)為匹配的緩沖區(qū)字符串的位置,默認(rèn)是從開始位置匹配

需要注意的是,pexpext不會(huì)解析shell命令中的元字符,包括重定向> 管道|或者通配符,此時(shí)可以將三個(gè)特殊元字符的命令作為/bin/bash的參數(shù)進(jìn)行調(diào)用

child =expect.spwan('/bin/bash -c "ls -l | grep LOG> logs.txt"')
child.expect(pexpect.EOF)

可以通過將命令的參數(shù)以PYTHON列表的方式進(jìn)行替換,從而使得語法更加清晰,下面的代碼等同于上面的代碼

shell_cmd='ls -l | grep LOG >logs.txt'
child=pexpext.spwan('/bin/bash',['-c,shell_cmd])
child.expect(pexpect.EOF)

在調(diào)試代碼時(shí),希望獲取pexpect的輸入與輸出信息,以便了解匹配的情況,一種時(shí)寫到日志中,另一種時(shí)輸出到標(biāo)準(zhǔn)輸出

寫到日志中

chidl-pexpect.spwan('some_command')
fout=file('mylog.txt,'w')
child.logfile=fout

輸出到標(biāo)準(zhǔn)輸出的方法

child=pexpect.swpan('some_command')
chuld.logfile=sys.stdout

以下為SSH遠(yuǎn)程登錄舉例,登錄成功后顯示/home目錄的文件并且記錄輸入與輸出

import pexpect
import sys

child=pexpect.spawn('ssh root@172.31.208.129')
fout=open('mylog.txt','w')
child.logfile=fout
#child.logfile=sys.stdout

child.expect('password:')
child.sendline('abc@123')
child.expect('#')
child.sendline('ls /home')
child.expect('#')

expect方法

expect定義了子程序輸出的匹配規(guī)則

方法定義:expect(pattern,timeout=-1,searchwindowsize=-1)

其中,參數(shù)pattern表示字符串,pexpext.EOF(指向緩沖區(qū),無匹配項(xiàng))、pexpect,TIMEOUT(匹配等待超時(shí)),正則表達(dá)式或者列表

參數(shù)timeout指定了等待匹配結(jié)果的超時(shí)時(shí)間,單位為秒,當(dāng)超時(shí)被觸發(fā)的時(shí)候,expect將匹配到pexpext.TIMEOUT,參數(shù)searchwindowsize為匹配的緩沖字符串的位置,默認(rèn)時(shí)從開始的位置匹配

read相關(guān)方法

下面的的方法作用都是向子程序發(fā)送響應(yīng)命令

send(self,s) #發(fā)送命令,不回車
sendline(self,s=' '),#發(fā)送命令,回車
snedcontrol(self.char) #發(fā)送控制字符
sendeof() #發(fā)送eof

run函數(shù)

run時(shí)使用pexpext進(jìn)行封裝的調(diào)用外部命令的的函數(shù)

from pexpect import *
run('scp foo user@example.com:.',events={'(?i)password':mypassword])

pxssh類

針對(duì)ssh會(huì)話操作上再做一次封裝

class pexpext.pxssh.pxssh(timeout=30,maxread=2000,searchwindwosize=None,logfile=None,cwd=None,env=None)

常用方法

  • login()建立ssh連接
  • logout() 斷開連接
  • promp()等待系統(tǒng)提示符,用于等待命令執(zhí)行結(jié)束
import pxssh
import getpass
try:
  s = pxssh.pxssh()                 #創(chuàng)建對(duì)象s
  hostname = raw_input('hostname: ')
  username = raw_input('username: ')
  password = getpass.getpass('password: ')  #接收密碼輸入
  s.login (hostname, username, password)   #建立ssh連接
  s.sendline ('uptime') # 運(yùn)行uptime命令
  s.prompt()       # 匹配系統(tǒng)提示符
  print s.before     # 打印系統(tǒng)體術(shù)符號(hào)出現(xiàn)前的命令輸出
  s.sendline ('ls -l')
  s.prompt()
  print s.before
  s.sendline ('df')
  s.prompt()
  print s.before
  s.logout()
except pxssh.ExceptionPxssh, e:
  print "pxssh failed on login."
  print str(e)

FTP自動(dòng)操作

實(shí)現(xiàn)自動(dòng)交互登錄FTP操作

import pexpect
import sys

child = pexpect.spawnu('ftp ftp.openbsd.org') #運(yùn)行ftp命令
child.expect('(?i)name .*: ')   #(?!)表示后面的字符串正則表達(dá)式忽略大小寫
child.sendline('anonymous')  # 輸入ftp賬號(hào)信息
child.expect('(?i)password')  #匹配密碼提示
child.sendline('pexpect@sourceforge.net')  
child.expect('ftp> ')
child.sendline('bin')   #啟用二進(jìn)制傳輸
child.expect('ftp> ')
child.sendline('get robots.txt') 
child.expect('ftp> ')
sys.stdout.write (child.before)  #輸出匹配的"ftp"之前的輸入與輸出操作
print("Escape character is '^]'.\n")
sys.stdout.write (child.after)
sys.stdout.flush()
child.interact() # Escape character defaults to ^]  #讓出控制權(quán),用戶可以繼續(xù)當(dāng)前會(huì)話手工控制子程序,默認(rèn)輸入"^]"字符跳出
child.sendline('bye')
child.close()

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python中filter函數(shù)的用法示例代碼

    python中filter函數(shù)的用法示例代碼

    filter() 函數(shù)用于過濾序列,過濾掉不符合條件的元素,返回一個(gè)迭代器對(duì)象,如果要轉(zhuǎn)換為列表,可以使用 list() 來轉(zhuǎn)換,這篇文章主要介紹了python中filter函數(shù)的用法,需要的朋友可以參考下
    2022-12-12
  • Python TKinter如何自動(dòng)關(guān)閉主窗口

    Python TKinter如何自動(dòng)關(guān)閉主窗口

    這篇文章主要介紹了Python TKinter如何自動(dòng)關(guān)閉主窗口,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • python中的編碼和解碼及\x和\u問題

    python中的編碼和解碼及\x和\u問題

    這篇文章主要介紹了python中的編碼和解碼及\x和\u問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 在python中實(shí)現(xiàn)調(diào)用可執(zhí)行文件.exe的3種方法

    在python中實(shí)現(xiàn)調(diào)用可執(zhí)行文件.exe的3種方法

    今天小編就為大家分享一篇在python中實(shí)現(xiàn)調(diào)用可執(zhí)行文件.exe的3種方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • 教你用Python寫一個(gè)京東自動(dòng)下單搶購腳本

    教你用Python寫一個(gè)京東自動(dòng)下單搶購腳本

    很多朋友都有網(wǎng)購搶購限量商品的經(jīng)歷,有時(shí)候蹲點(diǎn)搶怎么也搶不到,今天小編帶你們學(xué)習(xí)怎么用Python寫一個(gè)京東自動(dòng)下單搶購腳本,以后再也不用拼手速拼網(wǎng)速啦,快來一起看看吧
    2023-03-03
  • pytorch 實(shí)現(xiàn)在一個(gè)優(yōu)化器中設(shè)置多個(gè)網(wǎng)絡(luò)參數(shù)的例子

    pytorch 實(shí)現(xiàn)在一個(gè)優(yōu)化器中設(shè)置多個(gè)網(wǎng)絡(luò)參數(shù)的例子

    今天小編就為大家分享一篇pytorch 實(shí)現(xiàn)在一個(gè)優(yōu)化器中設(shè)置多個(gè)網(wǎng)絡(luò)參數(shù)的例子,具有很好參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • 最新評(píng)論