Python 如何使用子流程模块与ssh交互
我正在尝试使用subprocess生成一个ssh子进程 我正在Windows7上开发Python2.7.6 这是我的密码:Python 如何使用子流程模块与ssh交互,python,subprocess,popen,Python,Subprocess,Popen,我正在尝试使用subprocess生成一个ssh子进程 我正在Windows7上开发Python2.7.6 这是我的密码: from subprocess import * r=Popen("ssh sshserver@localhost", stdout=PIPE) stdout, stderr=r.communicate() print(stdout) print(stderr) 产出: None 标准输出应包含: sshserver@localhost的密码:下面是一个工作SSH代码的
from subprocess import *
r=Popen("ssh sshserver@localhost", stdout=PIPE)
stdout, stderr=r.communicate()
print(stdout)
print(stderr)
产出:
None
标准输出应包含:
sshserver@localhost的密码:下面是一个工作SSH代码的示例,该代码处理证书部分的是/否提示以及请求密码时的提示
#!/usr/bin/python
import pty, sys
from subprocess import Popen, PIPE, STDOUT
from time import sleep
from os import fork, waitpid, execv, read, write
class ssh():
def __init__(self, host, execute='echo "done" > /root/testing.txt', askpass=False, user='root', password=b'SuperSecurePassword'):
self.exec = execute
self.host = host
self.user = user
self.password = password
self.askpass = askpass
self.run()
def run(self):
command = [
'/usr/bin/ssh',
self.user+'@'+self.host,
'-o', 'NumberOfPasswordPrompts=1',
self.exec,
]
# PID = 0 for child, and the PID of the child for the parent
pid, child_fd = pty.fork()
if not pid: # Child process
# Replace child process with our SSH process
execv(command[0], command)
## if we havn't setup pub-key authentication
## we can loop for a password promt and "insert" the password.
while self.askpass:
try:
output = read(child_fd, 1024).strip()
except:
break
lower = output.lower()
# Write the password
if b'password:' in lower:
write(child_fd, self.password + b'\n')
break
elif b'are you sure you want to continue connecting' in lower:
# Adding key to known_hosts
write(child_fd, b'yes\n')
elif b'company privacy warning' in lower:
pass # This is an understood message
else:
print('Error:',output)
waitpid(pid, 0)
您无法立即读取stdin
的原因(如果我在这里错了,请纠正我),是因为SSH作为子进程运行,它使用不同的进程ID,您需要读取/附加到该进程ID
由于您使用的是windows,pty
将无法工作。有两种解决方案工作得更好,正如有人指出的那样,基于密钥的身份验证
为了实现基于密钥的身份验证,您只需执行以下操作:
在客户端上,运行:ssh-keygen
将您的id\u rsa.pub
内容(一行)复制到服务器上的/home/user/.ssh/authorized\u keys
中
你完成了。
如果没有,请选择pexpect
import pexpect
child = pexpect.spawn('ssh user@host.com')
child.expect('Password:')
child.sendline('SuperSecretPassword')
至少在Linux(和prob windows)上,tty的
stdin
与ssh请求的密码不同。等一下,有了这方面的代码(LinuxTho)。如果您需要自动化ssh
,您可能需要研究类似的东西。您可能还想考虑只使用基于密钥的身份验证,这样您就不需要用密码来处理了。我已经在pWEY上工作了,但是它在Windows上不太完美,这就是为什么我想使用标准Python模块@larsks@user3249194您不能为此使用标准模块。Windows不允许您连接到子进程ID。我读到有人摆弄win32库,试图更改主循环的进程权限,以便附加到子进程ID并读取标准输出。但简而言之,这是不可能的。我已经在下面公布了你的3个已知有效的选项。第一个是Linux解决方案,所以你可能对此不感兴趣,除非你想掌握生活并使用合适的操作系统,呵呵:)@Torxed我已经安装了debian并与pexpect合作,但是我想为windows找到一个解决方案:DTPTY模块需要termios,它只在Unix平台上工作,我在回答中提到过,不是吗/是的,你说了,我也说过我在windows上工作;)这就是为什么我发布了另外两个在Windows中工作的解决方案;)注意:Linux修复程序适用于阅读本文的任何其他人(因为这是一个常见问题,会有很多其他人来到这里),而且您现在有一台Linux机器,因此这也会对您有所帮助:您的答案中的解决方案在Windows上不起作用pexpect
needspty
需要一个POSIX系统(pty
是为Linux编写的)。