如何使用pexpect处理SSH会话?

时间:2018-04-10 18:15:21

标签: python pexpect

我正在尝试自动执行需要几个步骤的小任务,并且所有“设备”的某些步骤都是相同的: - ssh登录 - 运行命令 - 自己清理

我有一个使用pexpect的脚本但是对于每个函数(任务)我必须建立SSH连接,这是蹩脚的。

我想做的是这样的:

将创建会话的函数和使用相同“子”的其他函数

def ssh_login(device):
    child.spawn("ssh root@"+device)
    child.expect("password:")
    child.sendline(password)
    child.expect("#")

另一个使用会话并运行某些命令的函数,如

def run_command():
    # run some command here
    child.sendline("some_command")
    child.expect("#")

清理功能

def cleanup():
    child.sendline(cleanup)
    child.expect("#")
    child.sendline("exit")
    child.interract()

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

赞:

pexpect.spawn('ssh', [ '-o' + 'ControlMaster=auto',username + "@" + hostname, '-o' + 'ControlPath=~/.ssh/master-%r@%h:%p'])

您将找到会话:

ls ~/.ssh/master-yourname@hostname:22

答案 1 :(得分:0)

我做了类似的事情。您所需要做的就是return函数中的孩子ssh_login并将其作为输入传递给其他函数。

def ssh_login(device):
    child = pexpect.spawn("ssh root@"+device)
    #Do your usual login
    return child

调用它时,将子级保存在变量中。

session = ssh_login(my_device)
run_command(session)
cleanup(session)

当然,您需要更改其他功能以接受会话输入:

def run_command(session):
    # run some command here
    session.sendline("some_command")
    session.expect("#")

def cleanup(session):
    session.sendline(cleanup)
    session.expect("#")
    session.sendline("exit")
    session.interract()

答案 2 :(得分:-1)

当我使用python和SSH做任何事情时,我使用Paramiko,它是一个非常可靠的模块,对于任何使用它的项目,这都是我的“入门代码”。我已经对它进行了解释,并添加了一些注释,您可能希望生成一个要运行命令的服务器列表,然后循环它。我会建议,如果你需要经常在很多服务器上运行命令,考虑使用Saltstack或Ansible之类的东西,它们可以让你很容易定期管理服务器。

https://saltstack.com/

https://www.ansible.com/

 #!/usr/bin/env python

    import paramiko


    def run_ssh_cmd(remote_server, connect_user, identity, cmd=None):
        """ create an ssh connection to the remote server and retrieve
        information"""

        # kludge to make ssh work - add 'your_domain.com' to the remote_server
        remote_server += '.your_domain.com'

        client = paramiko.SSHClient()
        client.load_system_host_keys()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        client.connect(remote_server, username=connect_user, key_filename=identity)
        command_str = cmd
        stdin, stdout, stderr = client.exec_command(command_str)

        print stdout.readlines()
        client.close()

    if __name__ == '__main__':
        import sys
        import argparse
        import datetime

        parser = argparse.ArgumentParser()

        parser.add_argument("-s", "--server", action="store", required=True,
                            dest="server", help="Server to query")
        parser.add_argument("-u", "--user", action="store", required=True,
                            dest="user", help="User ID for remote server connection")
        parser.add_argument("-i", "--identity", action="store", required=True,
                            dest="id_file", help="SSH key file")
        args = parser.parse_args()

        run_ssh_cmd(args.server, args.user, args.id_file, "hostname;date")