You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 06:59:29