如何在Python中从子进程向SSH传递命令

时间:2017-03-15 16:08:05

标签: python bash ssh subprocess

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

我只是想知道是否有人不介意告诉我现在的情况

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

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

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

运行远程命令就像将其放在命令行上一样简单。 (这可以通过协议级别的SSH服务器与stdin上的服务器进行区分,但是所讨论的协议是为程序化使用而构建的,而不是为人类使用而构建的 - 因为后者是交互式shell模型背后的设计意图)

顺便说一句,如果你想在仅验证一次后通过单个连接通过不同的SSH调用运行多个命令,我强烈建议使用Paramiko,但你可以做到使用SSH multiplexing support

的OpenSSH命令行工具

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

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

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

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

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

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

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

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

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

那说,具体通过临时系统ssh'ing,你不需要经历这么多麻烦:你可以告诉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])

答案 1 :(得分:0)

根据您的评论,您说您可以联系。所以在那之后,要使用子进程通过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

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

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