Cha*_*l72 10 python linux ssh subprocess python-3.x
我正在尝试使用scp(安全复制)命令subprocess.Popen.登录要求我发送密码:
from subprocess import Popen, PIPE
proc = Popen(['scp', "user@10.0.1.12:/foo/bar/somefile.txt", "."], stdin = PIPE)
proc.stdin.write(b'mypassword')
proc.stdin.flush()
Run Code Online (Sandbox Code Playgroud)
这会立即返回错误:
user@10.0.1.12's password:
Permission denied, please try again.
Run Code Online (Sandbox Code Playgroud)
我确定密码是正确的.我通过手动调用scpshell 轻松验证它.那么为什么这不起作用呢?
请注意,有许多类似的问题,询问subprocess.Popen并发送自动SSH或FTP登录的密码:
如何从python脚本在linux中设置用户密码?
使用子进程发送密码
这些问题的答案不起作用和/或不适用,因为我使用的是Python 3.
sjb*_*jbx 10
这是ssh使用密码的函数pexpect:
def ssh(host, cmd, user, password, timeout=30, bg_run=False):
"""SSH'es to a host using the supplied credentials and executes a command.
Throws an exception if the command doesn't return 0.
bgrun: run command in the background"""
fname = tempfile.mktemp()
fout = open(fname, 'w')
options = '-q -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oPubkeyAuthentication=no'
if bg_run:
options += ' -f'
ssh_cmd = 'ssh %s@%s %s "%s"' % (user, host, options, cmd)
child = pexpect.spawn(ssh_cmd, timeout=timeout)
child.expect(['password: '])
child.sendline(password)
child.logfile = fout
child.expect(pexpect.EOF)
child.close()
fout.close()
fin = open(fname, 'r')
stdout = fin.read()
fin.close()
if 0 != child.exitstatus:
raise Exception(stdout)
return stdout
Run Code Online (Sandbox Code Playgroud)
应该可以使用类似的东西scp.
OpenSSH scp实用程序调用ssh程序以建立与远程主机的SSH连接,并且ssh进程处理身份验证.该ssh实用程序不接受命令行或其标准输入上的密码.我相信这是OpenSSH开发人员的一个深思熟虑的决定,因为他们认为人们应该使用更安全的机制,如基于密钥的身份验证.任何调用ssh的解决方案都将遵循以下方法之一:
ssh通过调用另一个命令,描述以获取密码这里或这里,或在一些问题的答案在这里.ssh可以按您希望的方式工作的修改版本.在这种特殊情况下,鉴于您已经scp从python脚本调用,似乎其中一个是最合理的方法:
Pexpect 有一个专门用于此的库:pxssh
http://pexpect.readthedocs.org/en/stable/api/pxssh.html
import pxssh
import getpass
try:
s = pxssh.pxssh()
hostname = raw_input('hostname: ')
username = raw_input('username: ')
password = getpass.getpass('password: ')
s.login(hostname, username, password)
s.sendline('uptime') # run a command
s.prompt() # match the prompt
print(s.before) # print everything before the prompt.
s.logout()
except pxssh.ExceptionPxssh as e:
print("pxssh failed on login.")
print(e)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46028 次 |
| 最近记录: |