所以我知道你可以使用Pexpect
来解决这个问题,但我不想依赖额外的库来解决除Python3提供的问题以外的其他问题。Python + SSH密码验证(无需外部库或公钥/私钥)?
我也知道生成公共密钥并允许它们在远程主机上是理想的,但这就是我打算使用此脚本(在正确位置设置密钥等)的一种方式。
这是我从SO社区获得的一大堆帮助之后获得的“我自己的”。 我很困难检查分叉的子伪终端是否执行了它应该与否。这意味着我可以判断SSH是否执行完毕,因为只要run()
函数正在运行,它就会持续运行。
(我pid_exists
将返回True
,只要它的run()的操作中。如果我退出run()
迅速SSH会话将没有足够的时间去做它应该做的)
#!/usr/bin/python
import pty, sys
from subprocess import Popen, PIPE, STDOUT
from time import sleep
from os.path import expanduser, abspath
from os import walk, setsid, fork, waitpid, execv, read, write, kill
def pid_exists(pid):
"""Check whether pid exists in the current process table."""
if pid < 0:
return False
try:
kill(pid, 0)
except (OSError, e):
return e.errno == errno.EPERMRM
else:
return True
class ssh():
def __init__(self, host, execute='echo "done" > /root/testing.txt', user='root', password=b'SuperPassword'):
self.exec = execute
self.host = host
self.user = user
self.password = password
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)
while True:
output = read(child_fd, 1024).strip()
print(output)
lower = output.lower()
# Write the password
if b'password:' in lower:
write(child_fd, self.password + b'\n')
break
elif 'are you sure you want to continue connecting' in lower:
# Adding key to known_hosts
write(child_fd, b'yes\n')
elif 'company privacy warning' in lower:
pass # This is an understood message
else:
print('Error:',output)
sleep(5)
print(pid_exists(pid))
ssh('10.10.10.1')
我找不到很多(或任何)有关如何获取Python打开并传输给我的伪伪终端的执行过程的信息。 我可以或应该参与子过程:https://stackoverflow.com/a/12235442/929999或有其他方法吗?