我正在尝试使用subprocess.Popen
运行scp
(安全复制)命令。登录要求我发送密码:
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()
这将立即返回错误:
user@10.0.1.12's password:
Permission denied, please try again.
我 * 肯定 * 密码是正确的。我很容易通过手动调用shell上的scp
来验证它。那么为什么这不起作用呢?
请注意,有许多类似的问题,询问有关subprocess.Popen
的问题,并发送自动SSH或FTP登录的密码:
How can I set a users password in linux from a python script?
Use subprocess to send a password
这些问题的答案不起作用和/或不适用,因为我使用的是Python 3。
7条答案
按热度按时间9vw9lbht1#
下面是一个使用
pexpect
的ssh
函数:使用
scp
应该可以实现类似的操作。3z6pesqy2#
OpenSSH
scp
实用程序调用ssh
程序来建立到远程主机的SSH连接,ssh进程处理身份验证。ssh
实用程序不接受命令行或其标准输入中的口令。我相信这是OpenSSH开发人员的一个深思熟虑的决定。因为他们认为人们应该使用更安全的机制,如基于密钥的身份验证。1.使用SSH key而不是密码进行身份验证。
1.使用sshpass、expect或类似的工具自动响应密码提示。
1.使用(滥用)SSH_ASKPASS功能获取
ssh
,通过调用另一个命令(描述为here或here)或在某些答案here中获取密码。1.让SSH服务器管理员启用host-based authentication并使用它。请注意,基于主机的身份验证仅适用于某些网络环境。请参阅其他说明here和here。
1.使用perl、python、java或你喜欢的语言编写你自己的ssh客户端,大多数现代编程语言都有ssh客户端库,你可以完全控制客户端获取密码的方式。
1.下载ssh source code并构建一个修改后的
ssh
版本,它可以按照您想要的方式工作。1.使用不同的ssh客户端。有other ssh clients可供选择,既有免费的,也有商业的。其中一个可能比OpenSSH客户端更适合您的需要。
在这个特定的例子中,假设您已经从python脚本中调用了
scp
,那么下面的一种方法似乎是最合理的:1.使用python的expect模块pexpect来调用
scp
,并将密码提供给它。1.使用paramiko(python ssh实现)来完成ssh任务,而不是调用外部程序。
tvokkenx3#
您链接的第二个答案建议您使用Pexpect(这通常是与需要输入的命令行程序进行交互的正确方法)。
ftf50wuq4#
Pexpect有一个库,它完全适用于:pxssh文件
http://pexpect.readthedocs.org/en/stable/api/pxssh.html
2o7dmzc55#
我猜一些应用程序使用stdin与用户交互,而一些应用程序使用终端交互。在这种情况下,当我们使用PIPE写入密码时,我们是在写入stdin。但SCP应用程序从终端读取密码。由于子进程不能使用终端与用户交互,而只能使用stdin,因此我们不能使用子进程模块,必须使用pexpect通过scp复制文件。
请随意更正。
j13ufse26#
下面是我基于pexpect的scp函数。它除了可以处理密码外,还可以处理通配符(即多个文件传输)。要处理多个文件传输(即通配符),我们需要通过shell发出一个命令。请参考pexpect FAQ。
它可以这样使用:
7tofc5zh7#
这是我根据@小林和@sjbx发布的代码进行的重写,但目的是执行scp请求,所以要归功于这两个人。