Python 子进程 - 通过 SSH 运行多个 shell 命令

Posted

技术标签:

【中文标题】Python 子进程 - 通过 SSH 运行多个 shell 命令【英文标题】:Python subprocess - run multiple shell commands over SSH 【发布时间】:2013-11-22 22:10:53 【问题描述】:

我正在尝试打开从一个 Linux 机器到另一个 Linux 机器的 SSH 管道,运行一些 shell 命令,然后关闭 SSH。

我无法控制任何一个盒子上的包裹,所以织物或 paramiko 之类的东西是不可能的。

我有幸使用以下代码运行一个 bash 命令,在本例中为“正常运行时间”,但不知道如何一个接一个地发出命令。我期待类似的东西:

sshProcess = subprocess.call('ssh ' + <remote client>, <subprocess stuff>)
lsProcess = subprocess.call('ls', <subprocess stuff>)
lsProcess.close()
uptimeProcess = subprocess.call('uptime', <subprocess stuff>)
uptimeProcess.close()
sshProcess.close()

我缺少子流程模块的哪一部分?

谢谢

pingtest = subprocess.call("ping -c 1 %s" % <remote client>,shell=True,stdout=open('/dev/null', 'w'),stderr=subprocess.STDOUT)
if pingtest == 0:
  print '%s: is alive' % <remote client>
  # Uptime + CPU Load averages
  print 'Attempting to get uptime...'
  sshProcess = subprocess.Popen('ssh '+<remote client>, shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  sshProcess,stderr = sshProcess.communicate()
  print sshProcess
  uptime = subprocess.Popen('uptime', shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  uptimeProcess,stderr = uptimeProcess.communicate()
  uptimeProcess.close( )
  print 'Uptime         : ' + uptimeProcess.split('up ')[1].split(',')[0]
else:
  print "%s: did not respond" % <remote client>

【问题讨论】:

你可能想看看fabric,这是一个已经做了你想做的事情的框架fabric.readthedocs.org/en/1.8/# 我同意 Fabric 会很有用。不幸的是,我无法控制这两个盒子,只能访问。 【参考方案1】:

基本上,如果您调用子进程,它会创建一个本地子进程而不是远程子进程 所以你应该与 ssh 进程进行交互。所以沿着这条线: 但请注意,如果您动态构建我的目录,则容易受到 shell 注入,那么 END 行应该是唯一标识符 为了避免 END 行的唯一性问题,最简单的方法是使用不同的 ssh 命令

from __future__ import print_function,unicode_literals
import subprocess

sshProcess = subprocess.Popen(['ssh', 
                               <remote client>],
                               stdin=subprocess.PIPE, 
                               stdout = subprocess.PIPE,
                               universal_newlines=True,
                               bufsize=0)
sshProcess.stdin.write("ls .\n")
sshProcess.stdin.write("echo END\n")
sshProcess.stdin.write("uptime\n")
sshProcess.stdin.write("logout\n")
sshProcess.stdin.close()


for line in sshProcess.stdout:
    if line == "END\n":
        break
    print(line,end="")

【讨论】:

我收到一个错误,stdin 无法识别,所以我添加了模块名称。现在它只是挂起,直到我 CTRL+C 它。 sshProcess = subprocess.Popen(['ssh', remoteClient],stdin=subprocess.PIPE, stdout = subprocess.PIPE) sshProcess.stdin.write('ls') sshProcess.stdin.write('echo END') for line in sshProcess.stdout.readlines(): if line == "END\n": break print(line) sshProcess.stdin.write("uptime") sshProcess.stdin.write("echo END") for line in sshProcess.stdout .readlines(): if line == "END\n": break print(line) 伙计,这种格式让人头疼。 很抱歉发布一个老问题,但是当我尝试这个时,我在for line in stdout.readlines(): 线上得到IOError: File not open for reading。我用from sys import stdout。我用谷歌搜索但没有运气。知道为什么会这样吗? 标准输出是 sshProcess 而不是 sys。此外,我做了测试,一切都没有按预期工作。现在示例工作 当然这是旧的,但 END 技巧的替代方法是使用 sshProcess.stdin.write("logout\n") 作为最终输入。这将关闭 ssh 连接并在打印 sshProcess.stdout 时不再需要“if...break”

以上是关于Python 子进程 - 通过 SSH 运行多个 shell 命令的主要内容,如果未能解决你的问题,请参考以下文章

使用python子进程和ssh读取远程文件?

通过 python 子进程 SSH 后终端挂起

调用通过 ssh 创建子进程的 Python 脚本挂起

并行运行多个子进程 - python 2.7

Python:子进程并运行具有多个参数的 bash 脚本

Python线程化多个bash子进程?