所以我知道您可以使用Pexpect
来解决问题,但我不希望依赖Python3提供的库以外的其他库来解决问题。
我也知道生成公钥并允许它们在远程主机上使用是理想的,但这正是我打算使用此脚本的目的(在正确的位置设置密钥等)。
这是我在SO社区的帮助下"独自一人"取得的成就。我在检查分叉的子伪终端是否完成了它应该执行的操作。这意味着我可以判断SSH是否已经执行完毕,因为只要run()
函数在运行,它就会一直存在。
(只要在run()操作中,我的pid_exists
就会返回True
。如果我快速退出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'yesn')
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或者还有别的办法吗?
叹息。。再多一个谷歌就可以省去所有人的麻烦。
os.waitpid(pid, 0)
如何给子进程一个密码并同时获取stdout