开发手册 欢迎您!
软件开发者资料库

Python 使用pexpect执行scp命令(代码中指定密码)

通常使用scp命令向其它Linux服务器拷贝文件,可能需要输入其它服务器的帐号和密码。使用Python中使用pexpect可以在代码中指定帐号密码,进行批量多台服务器执行scp命令操作。本文主要介绍Python中使用pexpect执行scp命令并在代码中指定帐号和密码,自动化多台服务器批量操作的方法,以及相关的示例代码。

1、Expect工具语言

expect是一个简单的工具语言,它的作者对Expect的定义:是一个实现自动交互功能的软件套件(a software suite for automating interactive tools),使用expect,它能帮助我们在合适的情景下进行合适的交互。

expect 的核心功能,对于设定好的特定匹配形式,以相匹配的动作以应对。每一个expect后所跟的字符串(或者正则表达式)就是脚本所等待的匹配模式,每一个send 所做的工作就是对于各种的模式串,实施相应的动作。

相关文档:Python pexpect模块的使用及示例代码

2、pexpect模块的安装

可以使用pip安装pexpect,Python3可能需要使用pip3来安装。

pip install pexpect

3、单台服务器使用expect执行scp命令

可以使用expect模块执行命令将文件拷贝到另一台服务器上,代码如下,

import pexpectusername='root' aim_ip='192.168.31.11' password='Aa123456'source_file_path='/home/wonhero'aim_file_path='/home/'port=22password_key = '.*assword.*'command = f'scp {source_file_path}  {username}@{aim_ip}:{aim_file_path}'print("执行指令: ", command)try:    execute = pexpect.spawn(command)    execute.expect(password_key)    execute.sendline(password)    execute.expect(pexpect.EOF)    print("拷贝成功")except:    print("拷贝失败")

4、多台服务器批量使用expect执行scp命令

如需要将文件拷贝到多台服务器上,可以通过expect模块实现,代码如下,

import pexpectdef doScp(username='root',     aim_ip='192.168.31.11',     password='Aa123456',    source_file_path='/home/root/wonhero',    aim_file_path='/home/',    port=22):    password_key = '.*assword.*'    command = f'scp {source_file_path}  {username}@{aim_ip}:{aim_file_path}'    print("执行指令: ", command)    try:        execute = pexpect.spawn(command)        execute.expect(password_key)        execute.sendline(password)        execute.expect(pexpect.EOF)        print("拷贝成功")    except:        print("拷贝失败")def executeRemoteCommand(host_list,source_file_path, aim_file_path):    import threading    thread_list = []    for ip, username, password in host_list:        thread = threading.Thread(target = doScp, args = (username,ip,password,source_file_path,aim_file_path))        thread_list.append(thread)#将生成的线程添加到列表里    for t in thread_list:        t.start() #开始执行线程    for t in thread_list:        t.join() #挂起线程,到所有线程结束if __name__ == '__main__':    executeRemoteCommand([('192.168.31.21','root','Aa123456')],'/home/wonhero','/home/')