python代替shell脚本_自动化shell脚本except与python的pexpect模块
expect脚本
expect是什么
expect是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预。说白了,expect就是一套用来实现自动交互功能的软件。
在实际工作中,我们运行命令、脚本或程序时,这些命令、脚本或程序都需要从终端输入某些继续运行的指令,而这些输入都需要人为的手工进行。而利用expect,则可以根据程序的提示,模拟标准输入提供给程序,从而实现自动化交互执行
由于在linux中的一些命令不太适合于脚本的自动化运行,比如fdisk,telnet,ftp连接下载等,所以必须使用except来解决交换问题。
except基础
包含以下四个命令
命令
作用
send
用于向进程发送字符串
except
从进程接收字符串
spwan
启动新进程
interact
允许用户交互
send命令接收一个字符串参数,并将该参数发送到进程。
expect命令和send命令相反,expect通常用来等待一个进程的反馈,我们根据进程的反馈,再发送对应的交互命令。
spawn命令用来启动新的进程,spawn后的send和expect命令都是和使用spawn打开的进程进行交互。
interact命令用的其实不是很多,一般情况下使用spawn、send和expect命令就可以很好的完成我们的任务;但在一些特殊场合下还是需要使用interact命令的,interact命令主要用于退出自动化,进入人工交互。比如我们使用spawn、send和expect命令完成了ftp登陆主机,执行下载文件任务,但是我们希望在文件下载结束以后,仍然可以停留在ftp命令行状态,以便手动的执行后续命令,此时使用interact命令就可以很好的完成这个任务。
代码举例
#!/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
这是一段非常简单代码,演示了基本用法
#!/usr/bin/expect:使用expect来解释该脚本;
set timeout 30:设置超时时间,单位为秒,默认情况下是10秒;
set host "101.200.241.109":设置变量;
spawn ssh $username@$host:spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。它主要的功能是给ssh运行进程加个壳,用来传递交互指令;
expect "password":这里的expect也是expect的一个内部命令,这个命令的意思是判断上次输出结果里是否包含“password”的字符串,如果有则立即返回;否则就等待一段时间后返回,这里等待时长就是前面设置的30秒;
send "$password\r":当匹配到对应的输出结果时,就发送密码到打开的ssh进程,执行交互动作;
interact:执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。
这就是对上述这段简单简单脚本的分析,在上述的示例中,涉及到expect中一个非常重要的概念——模式-动作;即上述expect "password" {send "$password\r"}这句代码表达出来的含义。
模式-动作
结合着expect "password" {send "$password\r"}这句代码来说说“模式-动作”。简单的说就是匹配到一个模式,就执行对应的动作;匹配到password字符串,就输入密码
如下所示:
expect {
"password" {
send "$password\r"
exp_continue
}
eof
{
send "eof"
}
}
其中exp_continue表示循环式匹配,通常匹配之后都会退出语句,但如果有exp_continue则可以不断循环匹配,输入多条命令,简化写法。
传参
很多时候,我们需要传递参数到脚本中,现在通过下面这段代码来看看如何在expect中使用参数:
#!/usr/bin/expect
if {$argc < 3} {
puts "Usage:cmd "
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表示参数个数,而参数值存放在$argv中,比如取第一个参数就是[lindex $argv 0],以此类推。
FTP下载expect脚本
使用yum安装expect
yum install expect
按照如下编写expect脚本
#!/usr/bin/expect -f
set ip [lindex $argv 0] #脚本的第一个参数,远程主机的IP地址
set file [lindex $argv 1] #脚本的第二个参数,指定下载的文件名
set timeout 10 #设置超时时间10秒
spawn ftp $ip #运行ftp $ip命令
expect "Name*" #如果出现Name字符
send "anonymous \r" #则输入anoymous(匿名用户)并回车
expect "Password:*" #如果出现Password字符
send "\r" #则仅输入回车
expect "ftp>*" #如果出现ftp>字符
send "get $file\r" #则发送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 #结束循环匹配
给脚本加上可执行权限chmod +x expect_ftp_auto.exp
pexpect模块
pexpect可以理解为linux下的expect的python封装,通过pexpect可以实现ssh,ftp,passwd,telnet等命令的进行自动交互
安装pip install pexpect
简单实现ssh自动登录的示例如下:
import pexpect
child = pexpect.spwan('scp foo user#expample.com:.') #spwan启动scp程序
child.expect('Password:') #expect方法等待子程序产生的输出,判断是否匹配定义的字符串
#‘Password:'
child.sendline(mypassword) #匹配后则发送密码进行回应
核心组件
spawn类
spawn是pexpect的主要入口,功能是启动和控制子应用程序,以下是它的构造函数
class pexpect.spwan(command,args=[],timeout=30,maxread=2000,searchwindowsize=None,logfile=None,cwd=None,env=None,ignore_sighup=True)
其中,command参数可以是任意已知的系统命令,比如
child=pexpect.spawn('user/bin/ftp')
当子程序需要参数的时候,还可以使用python列表来代替参数,如
child = pexpect.spwan('user/bin/ssh user@example.com')
参数timeout为等待结果的超时时间,maxread为从终端控制台一次读取的最大字节数,searchwindowsize参数为匹配的缓冲区字符串的位置,默认是从开始位置匹配
需要注意的是,pexpext不会解析shell命令中的元字符,包括重定向> 管道|或者通配符,此时可以将三个特殊元字符的命令作为/bin/bash的参数进行调用
child =expect.spwan('/bin/bash -c "ls -l | grep LOG> logs.txt"')
child.expect(pexpect.EOF)
可以通过将命令的参数以PYTHON列表的方式进行替换,从而使得语法更加清晰,下面的代码等同于上面的代码
shell_cmd='ls -l | grep LOG >logs.txt'
child=pexpext.spwan('/bin/bash',['-c,shell_cmd])
child.expect(pexpect.EOF)
在调试代码时,希望获取pexpect的输入与输出信息,以便了解匹配的情况,一种时写到日志中,另一种时输出到标准输出
写到日志中
chidl-pexpect.spwan('some_command')
fout=file('mylog.txt,'w')
child.logfile=fout
输出到标准输出的方法
child=pexpect.swpan('some_command')
chuld.logfile=sys.stdout
以下为SSH远程登录举例,登录成功后显示/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定义了子程序输出的匹配规则
方法定义:expect(pattern,timeout=-1,searchwindowsize=-1)
其中,参数pattern表示字符串,pexpext.EOF(指向缓冲区,无匹配项)、pexpect,TIMEOUT(匹配等待超时),正则表达式或者列表
参数timeout指定了等待匹配结果的超时时间,单位为秒,当超时被触发的时候,expect将匹配到pexpext.TIMEOUT,参数searchwindowsize为匹配的缓冲字符串的位置,默认时从开始的位置匹配
read相关方法
下面的的方法作用都是向子程序发送响应命令
send(self,s) #发送命令,不回车
sendline(self,s=' '),#发送命令,回车
snedcontrol(self.char) #发送控制字符
sendeof() #发送eof
run函数
run时使用pexpext进行封装的调用外部命令的的函数
from pexpect import *
run('scp foo user@example.com:.',events={'(?i)password':mypassword])
pxssh类
针对ssh会话操作上再做一次封装
class pexpext.pxssh.pxssh(timeout=30,maxread=2000,searchwindwosize=None,logfile=None,cwd=None,env=None)
常用方法
login()建立ssh连接
logout() 断开连接
promp()等待系统提示符,用于等待命令执行结束
import pxssh
import getpass
try:
s = pxssh.pxssh() #创建对象s
hostname = raw_input('hostname: ')
username = raw_input('username: ')
password = getpass.getpass('password: ') #接收密码输入
s.login (hostname, username, password) #建立ssh连接
s.sendline ('uptime') # 运行uptime命令
s.prompt() # 匹配系统提示符
print s.before # 打印系统体术符号出现前的命令输出
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自动操作
实现自动交互登录FTP操作
import pexpect
import sys
child = pexpect.spawnu('ftp ftp.openbsd.org') #运行ftp命令
child.expect('(?i)name .*: ') #(?!)表示后面的字符串正则表达式忽略大小写
child.sendline('anonymous') # 输入ftp账号信息
child.expect('(?i)password') #匹配密码提示
child.sendline('pexpect@sourceforge.net')
child.expect('ftp> ')
child.sendline('bin') #启用二进制传输
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 ^] #让出控制权,用户可以继续当前会话手工控制子程序,默认输入"^]"字符跳出
child.sendline('bye')
child.close()
python代替shell脚本_自动化shell脚本except与python的pexpect模块相关推荐
- python测试开发实战_自动化平台测试开发:Python测试开发实战
领取成功 您已领取成功! 您可以进入Android/iOS/Kindle平台的多看阅读客户端,刷新个人中心的已购列表,即可下载图书,享受精品阅读时光啦! - | 回复不要太快哦~ 回复内容不能为空哦 ...
- python解释器的提示符是shell嘛_从PowerShell语法错误运行Python脚本
您的第一个>>> import os >>> os.system('.\\CleanupStops.py')语句以交互模式启动了Python解释器.如果你想从那里运 ...
- java源码如何启动脚本_使用Shell脚本如何启动/停止Java的jar程序
本文介绍如何使用Shell脚本来开启和停止jar程序的后台运行,以及如何实现out大文件的切分.另外,补充一些后台运行的小知识. 启动脚本:start_upload.sh #!/bin/sh nohu ...
- 再见python你好go语言_再见Shell,你好Python
我最终还是决定放弃Shell,转而使用Python.这是为什么呢?来看看这篇博文,和我一起讨论吧! 作为一名职业程序员,我有多年编写Shell脚本的经验.你可能现在跟我面临着类似的情况.在Shell取 ...
- flask执行python脚本_如何在Flask中运行python脚本
我有一个Flask脚本,可以创建网站并动态打印一些数据.-打印的数据应来自另一个python脚本. 我目前面临的问题是,如果我将执行python脚本的行放在执行Flask应用程序的行之前,它将运行Py ...
- python重新启动整个脚本_每次对脚本进行更改时,都需要在终端中重新启动python...
根据您的评论描述您的工作流程,我有一个建议: first, i run python3.1 in terminal second, i do "import module" the ...
- python删除图片文字_文字隐藏到图片的python脚本
本帖最后由 WyattHuang 于 2019-7-13 17:47 编辑 这是什么: 昨天写的一个能把文字隐藏在图片的python脚本 DEMO: 藏文字之前: 藏文字之后: 使用方法 下载 T2I ...
- python作者龟叔_龟叔和他的Python
经过了漫长的旅程,终于要看到主角Python了.Python是现在非常非常流行的编程语言,在我们能看到的大部分编程语言排行榜中,Python都能在前三甲中拥有一席之地 ,并且发展势头非常之猛,可以这么 ...
- python windows 客户端开发_如何在Windows上使用Python进行开发
本文由葡萄城技术团队于原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 一直以来C#都是微软在编程语言方面最为显著的Tag,但时至今日Python ...
最新文章
- JQ实现当前页面导航加效果(栏目页有效)
- Hibernate复习之Hibernate基本介绍
- 逻辑回归 logistic regression
- NTLDR is missing解决方法
- 《复杂》读书笔记(part6)--计算机中的自我复制
- php mongodb
- RGB与YUV格式简介
- vijos p1782——借教室(noip2012提高组第2题)
- kill -9 和 kill -15 的区别
- html 开发资料 英文,HTML 中的框架(国外英文资料).doc
- 深度学习根据文字生成图片教程(附python代码)
- 用OpenCV检测图像中的长方形画布或纸张并提取图像内容
- PBOC规范研究之四、文件结构及访问(转)
- ArrayUtils
- 冲动的惩罚 - 刀郎 - 新阿瓦尔古丽
- 极域电子教室软件怎么脱离控制_如何制定职业发展目标,才能避免“现实发展脱离职业规划”的问题...
- 求助:tp-link wr720n路由器,想刷打印服务器!
- 安卓桌面壁纸_梅糖桌面安卓手机版下载-梅糖桌面app官方版下载v2.2安卓版
- 网桥工作原理及题目分析
- 省市县三级联动JS代码
热门文章
- erp从内部集成起步第3版下载_SCM与ERP的区别在哪里呢?
- was环境通过HTTPS访问其他域名报错 CWPKI0022E: SSL 握手故障:已从目标主机:端口“。。。...
- Linux上安装Hadoop集群(CentOS7+hadoop-2.8.3)
- WorkSbell第10周2017
- Spark ML机器学习
- jquery版瀑布流
- [FW]修复ubutnu12.04+win7的grub2引导
- MessageFormat用法
- ffmpeg filter 实现画面旋转
- Win10之WSL编译Android7.1源码