【问题标题】:Python run mutiple ssh commands in the same sessionPython 在同一个会话中运行多个 ssh 命令
【发布时间】:2013-11-24 19:26:59
【问题描述】:

我的目标是使用 python 连接到 SSH 并进行身份验证,我可以使用 Paramiko 或 Fabric 进行验证。但我想在每次执行后保持会话打开并读取输入/输出。使用 paramiko,我只能在会话关闭之前运行 1 个命令,并且要求我再次进行身份验证并且会话挂起。而且由于织物使用的是 paramiko 库,因此它给了我同样的问题。比如我的目录结构是这样的

-首页

--myfolder1

--myfolder2

由于会话关闭,我想执行以下命令而无需重新验证。

(make connection)
run cmd: 'pwd'
output: /home
run cmd: 'cd myfolder2'
run cmd: 'pwd'
output: /home/myfolder2

现在有任何模块可以做到这一点吗?可以用原生 python 从头开始​​制作吗?而且这是不可能的……?

编辑添加了代码。没有新的 open_session 它会关闭,我无法运行任何命令。运行第一个命令后,将再次提示我进行身份验证,并创建一个无限循环。

Edit2如果它在每个命令后关闭,那么这根本就无法正常工作?

edit3 如果我在不同的服务器上运行它并使用 paramikio.SSHClient 执行 exec_command,它不会要求我重新进行身份验证,但如果我 'cd somedir' 然后 'pwd' 它会输出我是回到我创建的根目录。

class connect:

    newconnection = ''

    def __init__(self,username,password): 
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect('someserver', username=username,password=password,port=22,timeout=5)
        except:
            print "Count not connect"
            sys.exit()
        self.newconnection = ssh

    def con(self):
        return self.newconnection


#This will create the connection
sshconnection = connect('someuser','somepassword').con()

while True:
    cmd = raw_input("Command to run: ")
    if cmd == "":
        break
    try:
        transport = sshconnection.get_transport()
        transport.set_keepalive(999999)
        chan = transport.open_session() 
        chan.settimeout(3)
        chan.setblocking(0)
    except:
        print "Failed to open a channel"
        chan.get_exception()
        sys.exit()

    print "running '%s'" % cmd
    stdout_data = []
    stderr_data = []
    pprint.pprint(chan)
    nbytes = 4096
    chan.settimeout(5)
    chan.get_pty()
    chan.exec_command(cmd)
    while True:
        print "Inside loop " , chan.exit_status_ready()
        time.sleep(1.2)
        if chan.recv_ready():
            print "First if"
            stdout_data.append(chan.recv(nbytes))
        if chan.recv_stderr_ready():
            print "Recv Ready"
            stderr_data.append(chan.recv_stderr(nbytes))
        if chan.exit_status_ready():
            print "Breaking"
            break

    print 'exit status: ', chan.recv_exit_status()
    print ''.join(stdout_data)

【问题讨论】:

  • 这不是 Fabric 和 Paramiko 的正常行为,在会话中运行多个命令没有问题。你能发布你的代码吗?
  • 我编辑了我的帖子以包含我的代码

标签: python ssh fabric paramiko


【解决方案1】:

当您可以将命令连接成一个时,这可以通过使用普通模块来实现。试试

pwd ; cd myfolder2 ; pwd

作为命令。这应该可以工作,但是当您有更复杂的命令需要参数时会很快变得乏味,而当参数包含空格时会很糟糕。下一步是将包含所有命令的脚本复制到远程端并告诉ssh 执行所述脚本。

这种方法的另一个问题是 SSH 在所有命令都执行之前不会返回。

或者,您可以构建一个“命令服务器”,即一个简单的 TCP 服务器,用于侦听传入连接并执行发送给它的命令。写起来很简单,但也很不安全。同样,解决方案是将服务器变成一个(Python)脚本,该脚本从标准输入读取命令并通过 SSH 远程启动该脚本,然后发送命令。

【讨论】:

  • 是的,我希望命令基于返回的值。如果我找不到文件 A,那么我希望 ssh 执行触摸文件 A 而不是 cd A。并且为我的命令设置监听服务器也不是一个选项。有很多服务器,我宁愿把这个自包含到我控制的 1 个脚本中
猜你喜欢
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 2014-09-19
  • 1970-01-01
  • 2015-06-11
相关资源
最近更新 更多