通过Paramiko执行远程命令:scp等需密码命令遇权限拒绝问题求助
嘿,这个问题我之前也踩过坑!核心原因是scp这类需要交互式输入密码的命令,默认只会从**终端(tty)**读取输入,而Paramiko默认执行命令的exec_channel并没有分配tty,所以你通过stdin传的密码根本没被scp接收到,自然就报权限拒绝了。下面给你两种解决思路,优先推荐第一种:
方案一:用Paramiko内置的SFTP功能(推荐)
其实完全没必要调用scp命令,Paramiko本身就支持SFTP协议,而且因为已经通过SSH连接完成了身份认证,SFTP可以直接基于这个连接工作,不用再处理密码输入的问题,安全又稳定。
举个代码例子:
import paramiko # 先建立SSH连接 ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 这里填你的远程主机信息 ssh_client.connect('远程主机IP', username='你的用户名', password='你的SSH登录密码') # 获取SFTP客户端对象 sftp = ssh_client.open_sftp() # 上传文件:本地路径 → 远程主机路径 sftp.put('/本地电脑的文件路径/test.txt', '/远程主机的目标路径/test.txt') # 下载文件:远程主机路径 → 本地路径 sftp.get('/远程主机的文件路径/result.txt', '/本地电脑的目标路径/result.txt') # 记得关闭连接 sftp.close() ssh_client.close()
这种方式比调用scp命令靠谱多了,不用纠结交互式输入的问题,还能更灵活地控制文件传输(比如断点续传、权限设置等)。
方案二:如果一定要用scp命令(仅特殊场景)
如果因为某些特殊原因必须执行scp命令,那得给命令分配tty,然后通过交互式会话模拟输入密码。可以用Paramiko的invoke_shell创建交互式shell来实现:
import paramiko import time ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect('远程主机IP', username='你的用户名', password='你的SSH登录密码') # 创建交互式shell会话 shell = ssh_client.invoke_shell() # 发送scp命令(替换成你的实际命令) shell.send('scp /本地路径/file.txt 目标用户@目标主机:/远程路径/\n') # 等待远程主机输出密码提示,这里用sleep简单处理,也可以用循环监听输出 time.sleep(1) output = shell.recv(1024).decode() # 匹配密码提示字符串(不同系统可能提示语不同,比如有些是"Password:") if 'password:' in output.lower(): # 发送目标主机的密码 shell.send('目标主机的登录密码\n') # 等待命令执行完成,获取输出 time.sleep(3) output += shell.recv(4096).decode() print(output) ssh_client.close()
⚠️ 注意:这种方式非常脆弱,它完全依赖远程主机输出的密码提示字符串,如果对方系统是本地化语言(比如中文提示“密码:”),或者提示格式变化,代码就会失效。而且等待时间需要根据网络情况调整,很容易出现超时或匹配失败的问题,所以非必要不推荐用这种方式。
内容的提问来源于stack exchange,提问作者Pavarine
相关产品推荐
相关产品推荐

