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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19900754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:56:17  来源:igfitidea点击:

Python subprocess - run multiple shell commands over SSH

pythonsshsubprocess

提问by user2978190

I am trying to open an SSH pipe from one Linux box to another, run a few shell commands, and then close the SSH.

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

I don't have control over the packages on either box, so something like fabric or paramiko is out of the question.

我无法控制任何一个盒子上的包裹,所以像 fabric 或 paramiko 这样的东西是不可能的。

I have had luck using the following code to run one bash command, in this case "uptime", but am not sure how to issue one command after another. I'm expecting something like:

我很幸运使用以下代码运行了一个 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()

What part of the subprocess module am I missing?

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

Thanks

谢谢

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>

采纳答案by Xavier Combelle

basically if you call subprocess it creates a local subprocess not a remote one so you should interact with the ssh process. so something along this lines: but be aware that if you dynamically construct my directory it is suceptible of shell injection then END line should be a unique identifier To avoid the uniqueness of END line problem, an easiest way would be to use different ssh command

基本上,如果您调用子进程,它会创建一个本地子进程而不是远程子进程,因此您应该与 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="")