bash 如何将命令从 Python 中的子进程传递给 SSH

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42815060/
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-09-18 15:54:05  来源:igfitidea点击:

How to pass commands to an SSH from subprocess in Python

pythonbashsshsubprocess

提问by entity without identity

I have used the subprocessmodule in Python 2.7.6 to establish an SSH. I realise that this is not recommended, but I am unable to install other Python SSH libraries such as paramiko and fabric.

我已经使用subprocessPython 2.7.6 中的模块来建立 SSH。我意识到不推荐这样做,但是我无法安装其他 Python SSH 库,例如 paramiko 和 fabric。

I was just wondering if someone wouldn't mind just telling me how I'd now go about

我只是想知道是否有人不介意告诉我我现在该怎么做

sshProcess = subprocess.call(['ssh', '-t', '<REMOTE>', 'ssh', '<REMOTE>']) 

I want to carry out commands in REMOTEwith the subprocess approach. Is there any way to do this? Unfortunately, REMOTEis protected by a password which the user manually enters. If it helps, I'm running the Windows 10 Bash shell.

我想REMOTE用子流程方法执行命令。有没有办法做到这一点?不幸的是,REMOTE它受用户手动输入的密码保护。如果有帮助,我正在运行 Windows 10 Bash shell。

Any help is appreciated.

任何帮助表示赞赏。

回答by Charles Duffy

Running a remote command is as simple as putting it on the command line. (This is distinguishable to the SSH server at a protocol level from feeding it on stdin, but the protocol in question is built for programmatic use, vs built for human use -- as the latter was the design intent behind the interactive-shell model).

运行远程命令就像把它放在命令行上一样简单。(这与 SSH 服务器在协议级别上的区别在于将其提供给标准输入,但所讨论的协议是为编程使用而构建的,而不是为人类使用而构建的——因为后者是交互式外壳模型背后的设计意图) .

By the way, if you want to run multiple commands via distinct SSH invocations over a single connection after authenticating only once, I'd strongly suggest using Paramiko for this, but you cando it with OpenSSH command-line tools by using SSH multiplexing support.

顺便说一句,如果您想在仅进行一次身份验证后通过单个连接上的不同 SSH 调用运行多个命令,我强烈建议为此使用 Paramiko,但您可以使用 OpenSSH 命令行工具通过使用SSH 多路复用支持来实现.



Let's say you have an array representing your remote command:

假设您有一个表示远程命令的数组:

myCommand = [ 'ls', '-l', '/tmp/my directory name with spaces' ]

To get that into a string (in a way that honors the spaces and can't let a maliciously-selected name run arbitrary commands on the remote server), you'd use:

要将其转换为字符串(以尊重空格并且不能让恶意选择的名称在远程服务器上运行任意命令的方式),您可以使用:

myCommandStr = ' '.join(pipes.quote(n) for n in myCommand)

Now, you have something you can pass as a command line argument to ssh:

现在,您可以将一些内容作为命令行参数传递给 ssh:

subprocess.call(['ssh', '-t', hostname, myCommandStr])

However, let's say you want to nest this. You can just repeat the process:

但是,假设您想嵌套它。你可以重复这个过程:

myCommand = [ 'ssh', '-t', hostname1, myCommandStr ]
myCommandStr = ' '.join(pipes.quote(n) for n in myCommand)
subprocess.call(['ssh', '-t', hostname2, myCommandStr])

Because we aren't redirecting stdin or stdout, they should still be pointed at the terminal from which your Python program was started, so SSH should be able to execute its password prompts directly.

因为我们没有重定向 stdin 或 stdout,它们仍应指向启动 Python 程序的终端,因此 SSH 应该能够直接执行其密码提示。



That said, specificallyfor ssh'ing through an interim system, you don't need to go through this much trouble: You can tell sshto do that work for you with the ProxyJumpoption:

也就是说,特别是对于通过临时系统进行 ssh 连接,您不需要经历这么多麻烦:您可以ssh通过以下ProxyJump选项告诉您为您完成这项工作:

myCommand = [ 'ls', '-l', '/tmp/my directory name with spaces' ]
myCommandStr = ' '.join(pipes.quote(n) for n in myCommand)
subprocess.call(['ssh', '-o', 'ProxyJump=%s' % hostname1, hostname2, myCommandStr])

回答by Nick Hale

From your comment, you say you can connect. So after that, to interact over ssh using subprocess you will need something like:

从您的评论中,您说您可以连接。因此,在那之后,要使用子进程通过 ssh 进行交互,您将需要以下内容:

ssh = subprocess.Popen(['ssh', <remote client>],
                           stdin=subprocess.PIPE, 
                           stdout = subprocess.PIPE)
back  = ssh.stdout.readlines()
if result == []:
    error = ssh.stderr.readlines()
    print error
else:
    print back

then to send commands, like list directory, something like:

然后发送命令,例如列表目录,例如:

ssh.stdin.write("ls\n")