Python的Pexpect库

本文介绍Pexpect模块的应用案例,包括远程文件操作、FTP文件管理、网络连通性测试及远程主机监控。通过具体代码示例展示了如何利用Pexpect实现自动化SSH登录、文件夹创建、文件拷贝等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Pexpect 是一个用来启动子程序并对其进行自动控制的纯 Python 模块。 Pexpect 可以用来和像 ssh、ftp、passwd、telnet 等命令行程序进行自动交互。本文主要是针对ssh远程登录,然后执行简单的新建文件夹与拷贝任务

 

Pexpect 的安装:

下载:https://pypi.python.org/pypi/pexpect/

解压后在目录下运行:python setup.py install

 

Pexpect 的简单使用:

from pexpect import *

user = 'user'

host = 'host'

password = 'password'

 

#实现远程登录host机器并新建/home/download/wangling/test目录

command = 'sudo ssh -l '+user+' '+host+' sudo mkdir -p /home/download/wangling/test'

child = spawn(command , timeout=10   ) 

child.sendline(password)

 

#实现远程文件拷贝(将本机1.txt文件拷贝到host机器test2目录下2.txt)

command1 = 'sudo scp /home/download/wangling/test1/1.txt '+user+'@'+host+':/home/download/wangling/test2/2.txt'

child = spawn(command1 , timeout=10   )

child.sendline(password)

#!/usr/bin/env python
#-*-coding:utf-8-*-
#pexpect库向文件发送数据
from pexpect.fdpexpect import fdspawn

f=open('/home/acm506/桌面/python数据库/with.py','ab+')

child=fdspawn(f)
child.sendline('age sister')
f.seek(0)
age=child.expect('age')
#成功的标志
if age==0:
    child.sendline('age success!')
child.close()


#!/usr/bin/env python
#-*-coding:utf-8-*-
#ftp 协议进行文件管理
import os 
import sys
import re
import time
import os.path
import pexpect

#用户登入
def login_ftp():
    ftp=pexpect.spawn('ftp',cwd=cwd)
    if ftp.expect(prmpt)!=0:
        sys.exit()
    #连接ftps服务器
    ftp.sendline(''.join(('open ',ftps)))
    #提示用户名不成功
    if ftp.expect('Name')!=0:
        sys.exit()
    #发送用户名
    ftp.sendline(ftpuser)
    #提示用户名密码输入
    if ftp.expect('Password:')!=0:
        sys.exit()
    ftp.sendline(ftppw)
    if ftp.expect('230')!=0 or ftp.expect(prmpt)!=0:
        sys.exit()
    return ftp

#获取服务器下文件下所有的文件
def get_server_files(ftp):
    ftp.sendline('ls')
    if ftp.expect('226')!=0:
        sys.exit()
    #文件列表
    filelsts=ftp.before
    filelsts=filelsts.split('\n')
    #匹配多个空格
    remtch=re.compile('\s+')
    filelsts=[remtch.subn('',item.strip('\r'))[0] for item in filelsts if 'group' in item]
    filedict=dict()
    for item in filelsts:
        datas=item.split('')
        filedict[datas[-1]]={'mon':mons.index(datas[-4])+1,'day':int(datas[-3]),'time':datas[-2]}
    return filedict

#获得本地文件信息
def get_local_files():
    localfiles=os.listdir(cwd)
    localfilesdict=dict()
    for file in localfiles:
        t=time.ctime(os.stat(os.path.join(cwd,file)).st_mtime)#创建时间,修改时间
        datas=t.split()
        localfilesdict[file]={'mon':mons.index(datas[-4])+1,'day':int(datas[-3]),'time':datas[-2][:5]}
    return localfilesdict


#文件同步到服务器
def sync_files(ftp,localfilesdict,filedict):
    #需要同步的文件
    addfile=[]
    for file in localfilesdict.keys():
        if file not in filedict:
            addfile.append(file)
        if file in filedict:
            if localfiledict[file]['mon']>filedict[file]['mon'] or localfiledict[file]['day']>filedict[file]['day'] or localfilesdict[file]['time']>filedict[file]['time']:
                addfile.append(file)

    #删除服务器上有但是本地没有的文件信息
    delfile=set(filedict.keys())-set(localfilesdict.keys())
    
    #上传文件
    if addfile:
        for f in addfile:
            ftp.sendline('put '+f)
            if ftp.expect(['226',pexpect.EOF])==0:
                print('Upload success:',f)
            else:
                sys.exit()

    #删除文件
    if delfile:
        for f in delfile:
            ftp.sendline('delete '+f)
            if ftp.expect(['250',pexpect.EOF])==0:
                print('Del:',f)
            else:
                print('Permission denied:')
                sys.exit()

#退出ftp服务器
def exit_ftp(ftp):
    if ftp:
        ftp.sendcontrol('d')
        print(ftp.read().decode())

if __name__=='__main__':
    mons=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')
    cwd='/home/acm506/桌面/python数据库'
    #服务器提示符
    prmpt=['ftp>',pexpect.EOF]
    #本机ip
    ftps='192.168.1.167'
    #用户名匿名
    ftpuser='anoneymous'
    #ftpuser='hang'
    #ftppw='hang'
    ftppw='123'
    #登入ftp服务器
    ftp=login_ftp()
    #获取文件列表
    filedict=get_server_files(ftp)
    localfilesdict=get_local_files()
    #文件同步
    sync_files(ftp,localfilesdict,filedict)
    #退出服务器
    exit_ftp(ftp)

#!/usr/bin/env python
#-*-coding:utf-8-*-
#测试网路window下
from pexpect.popen_spawn import PopenSpawn
import pexpect.popen_spawn


def test_ip(ipaddr):
    child=PopenSpawn('cmd')
    child.sendline('ping %s' % ipaddr)
    child.sendline('exit')
    child.expect(pexpect.EOF)
    out=child.before.decode('gbk')
    per=out[:out.find('%')][-2:]
    per=[ch for ch in per if ch.isdigit()]
    per=int(''.join(per))
    if per>=100:
        print('网络不通!',ipaddr)
    elif 80>=per>=30:
        print('网络不稳定!',ipaddr)
    else:
        print('网络正常!',ipaddr)

if __name__=='__main__':
    addrlst=['192.168.1.167','192.168.1.1','8.8.8.8']
    for ip in addrlst:
        test_ip(ip)

#!/usr/bin/env python
#-*-coding:utf-8-*-
#写入python脚本
import pexpect.replwrap

child=pexpect.replwrap.python()

print(child.run_command('2*1'))

child=pexpect.replwrap.bash()
print(child.run_command('ls'))

#!/usr/bin/env python
#-*-coding:utf-8-*-
#ssh命令连接远程
from pexpect.pxssh import pxssh
import getpass

hostname='192.168.1.167'
user='root'
pw=getpass.getpass()
s=pxssh()
s.login(hostname,user,pw)
s.sendline('ls -l')
s.prompt()
print(s.before.decode())
#磁盘使用情况
s.sendline('df')
s.prompt()
print(s.before.decode())
s.sendline('poweroff')

s.logout()
#!/usr/bin/env python
#-*-coding:utf-8-*-
#逐个登录制定的多台远程主机,监控远程主机并依据相关信息要求用户处理
#登录多台指定的远程主机
#获取远程主机的系统状态
#对远程主机状态进行检查
#远程主机状态良好则输出相关信息
#远程主机负载过重则显示其状态信息,并由用户选择是否进入交互模式处理,同时记录处理日志
#退出登录
from pexpect.pxssh import pxssh
import pexpect

#登录远程
def login_host(host):
    s=pxssh()
    #连接远程
    if s.login(host[0],host[1],host[2]):
        return s

#获取远程主机CPU数量
def get_cpus(sshc):
    #cpu信息
    sshc.sendline('cat /proc/cpuinfo')
    #匹配
    res=sshc.expect(['cpu cores.*\r\n'.pexpect.EOF])
    if res==0:
        #匹配结构
        data=sshc.after.decode().split('\r\n')
        #cpu数量
        data=data[0]
        data=data[data.index(':')+1:]
        #数量
        cpucores=int(data)
        sshc.prompt()
        return cpucores
#远程主机负载状况
def get_cpu_load(sshc):
    sshc.sendline('uptime')
    if sshc.prompt():
        data=sshc.before.decode()
        data=data.strip('\r\n')
        data=data[data.rfind(':')+1:]
        data=data.split(',')
        return (float(data[0]),float(data[1]),float(data[2]))

#获取负载的信息
def get_cpu_stat(sshc):
    sshc.sendline('vmstat')
    sshc.prompt()
    print(sshc.before.decode())

#登入用户后,处理一定的信息
def user_deal(host,logfilename):
    s=login_host(host)
    if not s:
        print('Login Failure:',host[0])
        return
    try:
        #cpu的数量
        cpucores=get_cpus(s)
        if not cpucores:
            print('Do not get cpucores:',host[0])
            return 
        cpu_load=get_cpu_load(s)
        if cpu_load[2]>=cpucores or 1:
            get_cpu_stat(s)
            print("System is not healthy.Do you want to deal?(yes/no)")
            yn=input()
            if yn=='yes':
                with open(logfilename,'ab+') as f:
                    s.logfile=f
                    s.interact()
                    s.prompt()
                    s.logfile=None
        else:
            print('System is healthy:',host[0])
    except:
        print('Failure:',host[0])
    finally:
        s.logout()

if __name__=='__main__':
    hosts=[('192.168.1.22','root','123'),]
    logfilename='log.txt'
    for host in hosts:
        user_deal(host,logfilename)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值