以下是處理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子,你需要讀/附至。
由於您使用的是windows,因此pty
將無法使用。有兩種解決方案可以更好地發揮作用,這就是pexpect以及有人指出基於密鑰的身份驗證。
爲了實現你只需要做到以下幾點基於密鑰的認證: 在您的客戶端,運行:ssh-keygen
您id_rsa.pub
內容(一行)複製到/home/user/.ssh/authorized_keys
在服務器上。
你完成了。 如果沒有,請帶着重點。
import pexpect
child = pexpect.spawn('ssh [email protected]')
child.expect('Password:')
child.sendline('SuperSecretPassword')
至少在Linux上(和windows窗口),tty的'stdin'與ssh的'stdin'不一樣,要求輸入密碼。堅持下來,爲此獲得代碼(linux tho)。 – Torxed
如果您需要自動化'ssh',您可能需要調查[pexpect](http://pexpect.sourceforge.net/pexpect.html)或類似內容。您可能還想考慮只使用基於密鑰的身份驗證,以便您不需要密碼密碼。 – larsks
我已經在pexpect上工作過,但它在windows上不能正常工作,這就是爲什麼我要使用標準python模塊的原因@larsks – WannaBeGenius