fabric运维
fabric中文文档:http://fabric-chs.readthedocs.io/zh_CN/chs/
视频教程:http://study.163.com/course/courseMain.htm?courseId=1003852044
安装: pip3 install fabric3 (注:python3对应要装fabric3)
检查安装情况:fab --version
进入python3,
>>> import fabric
>>> dir(fabric)
新建目录: cd /usr/local/fabric
命令行命令:
fab -u 用户名 -p 密码 -H ‘10.0.0.202’ -- ‘netstat -anptu | grep 22'
fab -u 用户名 -p 密码 -H '10.0.0.202,10.0.0.203,10.0.0.204' -- 'uname-a'
fab -u 用户名 -p 密码 -H '10.0.0.203,10.0.0.204' -- 'yum clean all & yum repolist all'
fab -u 用户名 -p 密码 -H '10.0.0.203.10.0.0.204' -P(并行) --'reboot'
fab -u 用户名 -p 密码 -H '10.0.0.203,10.0.0.204' -P --'yum clean all & yum repolist all'
fab -u 用户名 -p 密码 -H '10.0.0.203,10.0.0.204' -- 'system stop firewalld.service'
fab -u 用户名 -p 密码 -H '10.0.0.202,10.0.0.203,10.0.0.204' -P -- 'yum -y install gpm* && service gpm start &&systemctl enable gpm.service'
fab -u用户名 -p 密码 -H '10.0.0.204' -- 'yum -y install httpd && systemctl start httpd.service && systemctl enable httpd.service'
浏览器输入10.0.0.204,可以进入apache界面,为安装正常
fab -u用户名 -p 密码 -H '10.0.0.204' -- 'netstat -anptu | grep 80'
备注:CentOS7服务使用方法
服务使用方法
systemctl start [服务文件名]
systemctl restart [服务文件名]
systemctl stop [服务文件名]
systemctl status [服务文件名]
设置开机启动
systemctl enable [服务文件名]
systemctl disable [服务文件名]
fabfile文件:
env.hosts = ['10.0.0.203','10.0.0.204'] 定义Ip或主机名列表
env.user = 'root' 定义用户名
env.port = 22 定义端口
env.password = '密码' 定义密码
env.password={'root@10.0.0.203:22':"密码",
'root@10.0.0.204:22':“密码”} 定义用户名、ip、端口、密码
env.gateway = '10.0.0.254' 定义网关
env.roledefs = {"webservice":["10.0.0.203","10.0.0.204"],
"dbservice":["10.0.0.210","10.0.0.211"] 定义角色分租
函数 定义:
from fabric.api import *
local    #执行本地命令,如local('uname -s')
lcd      #切换本地目录,如lcd('/home')
cd       #切换远程目录,如cd('/var/logs')
run      #执行远程命令,如run('free -m')
sudo     #sudo方式执行远程命令,如sudo('/etc/init.d/httpd start')
put      #上次本地文件导远程主机,如put('/home/user.info','/data/user.info')
get      #从远程主机下载文件到本地,如:get('/data/user.info','/home/user.info')
prompt   #获得用户输入信息,如:prompt('please input user password:')
confirm  #获得提示信息确认,如:confirm('Test failed,Continue[Y/N]?')
reboot   #重启远程主机,如:reboot()
@task    #函数修饰符,标识的函数为fab可调用的,非标记对fab不可见,纯业务逻辑
@runs_once   #函数修饰符,标识的函数只会执行一次,不受多台主机影响
@roles() #运行指定的角色组里,通过env.roledefs里的定义
from fabric.colors import *
print blue(text)
print cyan(text)
print green(text)
print magenta(text)
print red(text)
print white(text)
print yellow(text)
新建文件: vi fabfile.py (fab自动调用文档,其定义的每一个函数,就是一个命令)
fabfile.py中可写入文档如下:
from fabric.api import *
def host_type():
run('uname -s')
run('hostname')
fab -H localhost host_tpye (-H localhost指定本机运行)
env.hosts=[
'root@10.0.0.2:22',
'root@10.0.0.3:22']
env.password = '密码'
def host_type():
run('uname -s')
fab host_typt
新建文件 c.py
from fabric.api import * env.hosts = ["10.0.0.203","10.0.0.204"] env.passwords = { 'root@10.0.0.203:22':'z', 'root@10.0.0.204:22':'z'} env.roledefs = { 'webserver':['10.0.0.204'], 'dbserver':['10.0.0.203']} @task def show(): run("hostname") #run("netstat -anput | grep 22") #run("ls /root/") @task @roles('webserver') def install_httpd(): print('install webserver') @task @roles('dbserver') def install_mysql(): print('install_mysql') @task def run_all(): execute(show) execute(install_httpd) execute(install_mysql)
if __name__ == '__main__': execute(run_all)
fab -f c.py -l
fab -f c.py show
fab -f c.py run_all
python3 c.pu (对应文中if判断)
新建文件 d.py
from fabric.api import * from fabric.colors import * env.hosts = ["10.0.0.203","10.0.0.204"] env.passwords = { 'root@10.0.0.203:22':'z', 'root@10.0.0.204:22':'z'} env.roledefs = { 'webserver':['10.0.0.204'], 'dbserver':['10.0.0.203']} @task def local_cmd(): local('ls -la') with lcd('/usr/local'): local("ls -la") @task def runsudo1(): run('free -m') sudo('cat /etc/passwd') @task def cd1(): with cd('/etc'): run('ls -la') @task def put1(): put('d.py','/usr/local/') run('ls -la /usr/local/') @task def get1(): get('/usr/local/d.py','dd.py') local('ls -la') @task def prompt1(): content1 = prompt("请输入字符:") print(content1) @task def color1(): print(white('hello world!')) print(yellow('hello world!')) print(red('hello world!')) print(blue('hello world!')) print(green('hello world!')) print(cyan('hello world!')) print(magenta('hello world!'))
confirm
(env1) [root@centos7-3 env1]# python3 >>> from fabric.contrib.console import confirm >>> content = confirm('continue[Y/N]?') continue[Y/N]? [Y/n] y >>> content True >>> content = confirm('continue[Y/N]?') continue[Y/N]? [Y/n] n >>> content False
文件的打包 、上传、校验、下载:
打包:tar -czf xxx.tar.gz.xxx
解包:tar -zxf xxx.tar.gz -C 路径
上传:put('本地文件路径',‘远程文件路径’)
下载:get(‘远程文件路径’,‘本地文件路径’)
新建文件 e.py
1 from fabric.api import* 2 from fabric.contrib.console import confirm 3 from fabric.colors import * 4 5 env.hosts =['10.0.0.204'] 6 env.user = 'root' 7 8 env.passwords = { 9 'root@10.0.0.203:22':'z', 10 'root@10.0.0.204:22':'z'} 11 12 @task 13 def upload_file(): 14 with settings(warn_only=True): 15 local('tar -czf b.tar.gz b.py') 16 result = put('b.tar.gz','/usr/local/') 17 if result.failed and not confirm('continue[Y/N]?'): 18 abort('put b.tar.gz failed!') 19 with settings(warn_only=True): 20 local_file = local('md5sum b.tar.gz',capture=True).split(" ")[0] 21 remote_file = run('md5sum /usr/local/b.tar.gz').split(" ")[0] 22 if local_file == remote_file: 23 print(green('local == remote')) 24 else: 25 print(red('local != remote')) 26 run('mkdir /usr/local/test') 27 run('tar -zxf /usr/local/b.tar.gz -C /usr/local/test/') 28 29 @task 30 def download_file(): 31 with settings(warn_only=True): 32 get('/usr/local/b.tar.gz','/usr/local/b1.tar.gz') 33 local('mkdir /usr/local/test1') 34 local('tar -zxf /usr/local/b1.tar.gz -C /usr/local/test1')
多主机并行运维:
新建文件夹 f.py
@parallel #并行
from fabric.api import * env.user = "root" host1 = "10.0.0.202" host2 = "10.0.0.203" host3 = "10.0.0.204" env.hosts = [host1,host2,host3] env.passwords ={ "root@10.0.0.202:22":"z", "root@10.0.0.203:22":"z", "root@10.0.0.204:22":"z"} @task @parallel @hosts(host1,host2,host3) def install_ftp(): run("yum clean all") run("yum repolist all") run("yum -y install vsftpd") run("systemctl start vsftpd.service") run("systemctl enable vsftpd.service") run("systemctl status vsftpd.service")
以下文档转载自:http://blog.51cto.com/lizhenliang/1880856
第十八章 Python批量管理主机(paramiko、fabric与pexpect)
本章节主要讲解运维工程师比较感兴趣的知识,那就是运维批量管理,在Python下有paramiko、fabric和pexpect这三个模块可帮助运维实现自动化部署、批量执行命令、文件传输等常规任务,接下来一起看看它们的使用方法吧!
18.1 paramiko
paramiko模块是基于Python实现的SSH远程安全连接,用于SSH远程执行命令、文件传输等功能。
默认Python没有,需要手动安装:pip install paramiko
如安装失败,可以尝试yum安装:yum install python-paramiko
18.1.1 SSH密码认证远程执行命令
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/usr/bin/python# -*- coding: utf-8 -*-importparamikoimportsyshostname ='192.168.1.215'port =22username ='root'password ='123456'client =paramiko.SSHClient()  # 绑定实例client.set_missing_host_key_policy(paramiko.AutoAddPolicy())client.connect(hostname, port, username, password, timeout=5)stdin, stdout, stderr =client.exec_command('df -h')   # 执行bash命令result =stdout.read()error =stderr.read()# 判断stderr输出是否为空,为空则打印执行结果,不为空打印报错信息ifnoterror:   printresultelse:   printerrorclient.close() | 
18.1.2 私钥认证远程执行命令
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #!/usr/bin/python# -*- coding: utf-8 -*-importparamikoimportsyshostname ='192.168.1.215'port =22username ='root'key_file ='/root/.ssh/id_rsa'cmd =" ".join(sys.argv[1:])defssh_conn(command):    client =paramiko.SSHClient()    key =paramiko.RSAKey.from_private_key_file(key_file)    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())    client.connect(hostname, port, username, pkey=key)    stdin, stdout, stderr =client.exec_command(command)  # 标准输入,标准输出,错误输出    result =stdout.read()    error =stderr.read()    ifnoterror:        printresult    else:        printerror    client.close()if__name__ =="__main__":    ssh_conn(cmd) | 
18.1.3 上传文件到远程服务器
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #!/usr/bin/python# -*- coding: utf-8 -*-importos, sysimportparamikohostname ='192.168.1.215'port =22username ='root'password ='123456'local_path ='/root/test.txt'remote_path ='/opt/test.txt'ifnotos.path.isfile(local_path):    printlocal_path +" file not exist!"    sys.exit(1)try:    s =paramiko.Transport((hostname, port))    s.connect(username =username, password=password)exceptException as e:    printe    sys.exit(1)sftp =paramiko.SFTPClient.from_transport(s)# 使用put()方法把本地文件上传到远程服务器sftp.put(local_path, remote_path)       # 简单测试是否上传成功try:    # 如果远程主机有这个文件则返回一个对象,否则抛出异常                   sftp.file(remote_path)     print"上传成功."exceptIOError:    print"上传失败!"finally:    s.close() | 
18.1.4 从远程服务器下载文件
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #!/usr/bin/python# -*- coding: utf-8 -*-importos, sysimportparamikohostname ='192.168.1.215'port =22username ='root'password ='123456'local_path ='/root/test.txt'remote_path ='/opt/test.txt'try:    s =paramiko.Transport((hostname, port))    s.connect(username=username, password=password)    sftp =paramiko.SFTPClient.from_transport(s)exceptException as e:    printe    sys.exit(1)try:    # 判断远程服务器是否有这个文件    sftp.file(remote_path)    # 使用get()方法从远程服务器拉去文件    sftp.get(remote_path, local_path)       exceptIOError as e:    printremote_path +"remote file not exist!"    sys.exit(1)finally:    s.close()# 测试是否下载成功ifos.path.isfile(local_path):    print"下载成功."else:    print"下载失败!" | 
18.1.5 上传目录到远程服务器
paramiko模块并没有实现直接上传目录的类,已经知道了如何上传文件,再写一个上传目录的代码就简单了,利用os库的os.walk()方法遍历目录,再一个个上传:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #!/usr/bin/python# -*- coding: utf-8 -*-importos, sysimportparamikohostname ='192.168.1.215'port =22username ='root'password ='123456'local_path ='/root/abc'remote_path ='/opt/abc'# 去除路径后面正斜杠iflocal_path[-1] =='/':    local_path =local_path[0:-1]ifremote_path[-1] =='/':    remote_path =remote_path[0:-1]file_list =[]ifos.path.isdir(local_path):    forroot, dirs, files inos.walk(local_path):        forfileinfiles:            # 获取文件绝对路径            file_path =os.path.join(root, file)             file_list.append(file_path)else:    printpath +"Directory not exist!"    sys.exit(1)try:    s =paramiko.Transport((hostname, port))    s.connect(username=username, password=password)    sftp =paramiko.SFTPClient.from_transport(s)exceptException as e:    printeforlocal_file infile_list:    # 替换目标目录    remote_file =local_file.replace(local_path, remote_path)    remote_dir =os.path.dirname(remote_file)    # 如果远程服务器没目标目录则创建    try:        sftp.stat(remote_dir)    exceptIOError:        sftp.mkdir(remote_dir)    print"%s -> %s"%(local_file, remote_file)    sftp.put(local_file, remote_file)s.close() | 
sftp是安全文件传输协议,提供一种安全的加密方法,sftp是SSH的一部分,SFTPClient类实现了sftp客户端,通过已建立的SSH通道传输文件,与其他的操作,如下:
| sftp.getcwd() | 返回当前工作目录 | 
| sftp.chdir(path) | 改变工作目录 | 
| sftp.chmod(path, mode) | 修改权限 | 
| sftp.chown(path, uid, gid) | 设置属主属组 | 
| sftp.close() | 关闭sftp | 
| sftp.file(filename, mode='r', bufsize=-1) | 读取文件 | 
| sftp.from_transport(s) | 创建SFTP客户端通道 | 
| sftp.listdir(path='.') | 列出目录,返回一个列表 | 
| sftp.listdir_attr(path='.') | 列出目录,返回一个SFTPAttributes列表 | 
| sftp.mkdir(path, mode=511) | 创建目录 | 
| sftp.normalize(path) | 返回规范化path | 
| sftp.open(filename, mode='r', bufsize=-1) | 在远程服务器打开文件 | 
| sftp.put(localpath, remotepath, callback=None) | localpath文件上传到远程服务器remotepath | 
| sftp.get(remotepath, localpath, callback=None) | 从远程服务器remotepath拉文件到本地localpath | 
| sftp.readlink(path) | 返回一个符号链接目标 | 
| sftp.remove(path) | 删除文件 | 
| sftp.rename(oldpath, newpath) | 重命名文件或目录 | 
| sftp.rmdir(path) | 删除目录 | 
| sftp.stat(path) | 返回远程服务器文件信息(返回一个对象的属性) | 
| sftp.truncate(path, size) | 截取文件大小 | 
| sftp.symlink(source, dest) | 创建一个软链接(快捷方式) | 
| sftp.unlink(path) | 删除软链接 | 
博客地址:http://lizhenliang.blog.51cto.com
QQ群:323779636(Shell/Python运维开发群)
18.2 fabric
fabric模块是在paramiko基础上又做了一层封装,操作起来更方便。主要用于多台主机批量执行任务。
默认Python没有,需要手动安装:pip install fabric
如安装失败,可以尝试yum安装:yum install fabric
Fabric常用API:
| API类 | 描述 | 示例 | 
| local | 执行本地命令 | local('uname -s') | 
| lcd | 切换本地目录 | lcd('/opt') | 
| run | 执行远程命令 | run('uname -s') | 
| cd | 切换远程目录 | cd('/opt') | 
| sudo | sudo方式执行远程命令 | sudo('/etc/init.d/httpd start') | 
| put | 上传本地文件或目录到远程主机 | put(remote_path, local_path) | 
| get | 从远程主机下载文件或目录到本地 | put(local_path, remote_path) | 
| open_shell | 打开一个shell,类似于SSH连接到了远程主机 | open_shell("ifconfig eth0") | 
| prompt | 获得用户输入信息 | prompt('Please input user password: ') | 
| confirm | 获得提示信息确认 | confirm('Continue[Y/N]?') | 
| reboot | 重启远程主机 | reboot() | 
| @task | 函数装饰器,引用说明函数可调用,否则不可见 | |
| @runs_once | 函数装饰器,函数只会执行一次 | 
当我们写好fabric脚本后,需要用fab命令调用执行任务。
命令格式:fab [options] <command>[:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ...
fab命令有以下常用选项:
| 选项 | 描述 | 
| -l | 打印可用的命令(函数) | 
| --set=KEY=VALUE,... | 逗号分隔,设置环境变量 | 
| --shortlist | 简短打印可用命令 | 
| -c PATH | 指定本地配置文件 | 
| -D | 不加载用户known_hosts文件 | 
| -f PATH | 指定fabfile文件 | 
| -g HOST | 逗号分隔要操作的主机 | 
| -i PATH | 指定私钥文件 | 
| -k | 不加载来自~/.ssh下的私钥文件 | 
| -p PASSWORD | 使用密码认证and/or sudo | 
| -P | 默认为并行执行方法 | 
| --port=PORT | 指定SSH连接端口 | 
| -R ROLES | 根据角色操作,逗号分隔 | 
| -s SHELL | 指定新shell,默认是'/bin/bash -l -c' | 
| --show=LEVELS | 以逗号分隔的输出 | 
| --ssh-config-path=PATH | SSH配置文件路径 | 
| -t N | 设置连接超时时间,单位秒 | 
| -T N | 设置远程命令超时时间,单位秒 | 
| -u USER | 连接远程主机用户名 | 
| -x HOSTS | 以逗号分隔排除主机 | 
| -z INT | 并发进程数 | 
18.2.1 本地执行命令
| 1 2 3 4 5 6 7 | fromfabric.api importlocaldefcommand():    local('ls')# fab command[localhost] local: lsfabfile.py  fabfile.pyc  tab.py  tab.pycDone. | 
使用fab命令调用,默认寻找当前目录的fabfile.py文件。
18.2.2 远程执行命令
| 1 2 3 4 5 6 7 8 9 10 11 12 | fromfabric.api importrundefcommand():    run('ls')# fab -H 192.168.1.120 -u user command[192.168.1.120] Executing task 'command'[192.168.1.120] run: ls[192.168.1.120] Login password for'user':[192.168.1.120] out: access.log  a.py[192.168.1.120] out:Done.Disconnecting from192.168.1.120... done. | 
如果在多台主机执行,只需要-H后面的IP以逗号分隔即可。
18.2.3 给脚本函数传入位置参数
| 1 2 3 4 5 6 7 8 9 10 11 | fromfabric.api importrundefhello(name="world"):    print("Hello %s!"%name)# fab -H localhost hello[localhost] Executing task 'hello'Hello world!Done.# fab -H localhost hello:name=Python[localhost] Executing task 'hello'Hello Python!Done. | 
18.2.4 主机列表组
| 1 2 3 4 5 6 | fromfabric.api importrun, envenv.hosts =['root@192.168.1.120:22', 'root@192.168.1.130:22']env.password ='123.com'env.exclude_hosts =['root@192.168.1.120:22']   # 排除主机defcommand():   run('ls') | 
env作用是定义fabfile全局设定,类似于变量。还有一些常用的属性:
| env属性 | 描述 | 示例 | 
| env.hosts | 定义目标主机 | env.hosts = ['192.168.1.120:22'] | 
| env.exclude_hosts | 排除指定主机 | env.exclude_hosts = '[192.168.1.1]' | 
| env.user | 定义用户名 | env.user='root' | 
| env.port | 定义端口 | env.port='22' | 
| env.password | 定义密码 | env.password='123' | 
| env.passwords | 定义多个密码,不同主机对应不同密码 | env.passwords = {'root@192.168.1.120:22': '123'} | 
| env.gateway | 定义网关 | env.gateway='192.168.1.2' | 
| env.roledefs | 定义角色分组 | env.roledef = {'web':['192.168.1.11'], 'db':['192.168.1.12']} | 
| env.deploy_release_dir | 自定义全局变量,格式:env.+ '变量名' | env.var | 
18.2.5 定义角色分组
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # vi install.pyfromfabric.api importrun, envenv.roledefs ={    'web': ['192.168.1.10', '192.168.1.20'],    'db': ['192.168.1.30', '192.168.1.40']}env.password ='123'@roles('web')deftask1():   run('yum install httpd -y')@roles('db')deftask2():   run('yum install mysql-server -y')defdeploy():   execute(task1)   execute(task2)# fab -f install.py deploy | 
18.2.6 上传目录到远程主机
| 1 2 3 4 5 6 7 8 | fromfabric.api import*env.hosts =['192.168.1.120']env.user ='user'env.password ='123.com'deftask():   put('/root/abc', '/home/user')   run('ls -l /home/user')# fab task | 
18.2.7 从远程主机下载目录
| 1 2 3 4 5 6 7 8 | fromfabric.api import*env.hosts =['192.168.1.120']env.user ='user'env.password ='123.com'deftask():   get('/home/user/b', '/opt')   local('ls -l /opt')# fab task | 
18.2.8 打印颜色,有助于关键地方醒目
| 1 2 3 4 5 6 | fromfabric.colors import*defshow():   printgreen('Successful.')   printred('Failure!')   printyellow('Warning.')# fab show | 
经过上面演示fabric主要相关功能,是不是觉得很适合批量自动部署呢!没错,通过编写简单的脚本,即可完成复杂的操作。
博客地址:http://lizhenliang.blog.51cto.com
QQ群:323779636(Shell/Python运维开发群)
18.3 pexpect
pexpect是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的Python模块。暂不支持Windows下的Python环境执行。
这里主要讲解run()函数和spawn()类,能完成自动交互,下面简单了解下它们使用。
18.3.1 run()
run()函数用来运行bash命令,类似于os模块中的system()函数。
参数:run(command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None)
| 1 2 3 4 5 | 例1:执行ls命令>>> importpexpect>>> pexpect.run("ls") 例2:获得命令状态返回值>>> command_output, exitstatus =pexpect.run("ls", withexitstatus=1) | 
command_outout是执行结果,exitstatus是退出状态值。
18.3.2 spawn()
spawn()是pexpect模块主要的类,实现启动子程序,使用pty.fork()生成子进程,并调用exec()系列函数执行命令。
参数:spawn(command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None)
spawn()类几个常用函数:
| expect(pattern, timeout=-1, searchwindowsize=None) | 匹配正则表达式,pattern可以是正则表达式。 | 
| send(s) | 给子进程发送一个字符串 | 
| sendline(s='') | 就像send(),但添加了一个换行符(os.lineseq) | 
| sendcontrol(char) | 发送一个控制符,比如ctrl-c、ctrl-d | 
例子:ftp交互
用ftp命令登录是这样的,需要手动输入用户名和密码,才能登录进去。
| 1 2 3 4 5 6 7 8 9 10 11 | # ftp 192.168.1.10Connected to 192.168.1.10(192.168.1.10).220-FileZilla Server version 0.9.46beta220-written by Tim Kosse (tim.kosse@filezilla-project.org)220Please visit http://sourceforge.net/projects/filezilla/Name (192.168.1.10:root): yunwei331Password required foryunweiPassword:230Logged onRemote system typeisUNIX.ftp> | 
下面我们用pexpect帮我们完成输入用户名和密码:
| 1 2 3 4 5 6 7 8 9 10 11 | importpexpectchild =pexpect.spawn('ftp 192.168.1.10')child.expect('Name .*: ')child.sendline('yunwei')child.expect('Password:')child.sendline('yunweipass')child.expect('ftp> ')child.sendline('ls')child.sendline('bye')child.expect(pexpect.EOF)   # pexpect.EOF程序打印提示信息printchild.before   # 保存命令执行结果 | 
手动输入时,是来自键盘的标准输入,而pexpect是先匹配到关键字,再向子进程发送字符串。
pexpect.EOF打印提示信息,child.before保存的是命令执行结果。
通过上面的例子想必你已经知道pexpect主要功能了,在交互场景下很有用,这里就讲解这么多了,目的是给大家提供一个自动交互实现思路。
小结:
通过对Python下paramiko、fabric和pexpect模块使用,它们各有自己擅长的一面。
paramiko:方便嵌套系统平台中,擅长远程执行命令,文件传输。
fabric:方便与shell脚本结合,擅长批量部署,任务管理。
pexpect:擅长自动交互,比如ssh、ftp、telnet。
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号