You need to enable JavaScript to run this app. 本地Python经SSH跳板机执行SFTP操作的可靠实现方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

本地Python经SSH跳板机执行SFTP操作的可靠实现方案咨询

问题根因

原来的代码存在两个核心问题:

  • 每次调用exec_command都会创建独立的shell进程,第一次执行的sftp会话和第二次的ls完全无关,第二次的ls是在EC2本地shell执行的,返回的自然是EC2本地的目录内容
  • 直接往sftp的stdin写密码的方式不可靠,sftp的密码提示是交互式终端输出,默认exec_command不分配伪终端,输入的密码不会被sftp进程识别
可靠实现方案

方案1:SSH端口转发(跳板隧道,通用Python方案)

通过paramiko在本地和目标SFTP服务器之间建立跳板隧道,直接在本地操作SFTP,逻辑最清晰,也方便调试:

import paramiko
from paramiko import SSHClient, AutoAddPolicy

# 1. 先连接跳板EC2
jump_host = '你的EC2公网IP'
jump_user = 'EC2登录用户名'
jump_key = '/path/to/ec2/ssh/key.pem' # 也可以用密码认证

jump_ssh = SSHClient()
jump_ssh.set_missing_host_key_policy(AutoAddPolicy())
jump_ssh.connect(hostname=jump_host, username=jump_user, key_filename=jump_key)

# 2. 建立跳板到目标SFTP服务器的端口转发
target_host = '目标SFTP地址'
target_port = 22 # SFTP默认端口
local_bind_port = 9999 # 本地随便选一个未占用的端口

# 开通隧道
transport = jump_ssh.get_transport()
local_channel = transport.open_channel('direct-tcpip', (target_host, target_port), ('127.0.0.1', local_bind_port))

# 3. 直接通过本地隧道连接SFTP
sftp_ssh = SSHClient()
sftp_ssh.set_missing_host_key_policy(AutoAddPolicy())
# 连接的时候指向本地转发端口,流量会自动通过跳板发到目标SFTP
sftp_ssh.connect(hostname='127.0.0.1', port=local_bind_port, username='SFTP用户名', password='SFTP密码', sock=local_channel)

# 4. 正常操作SFTP
sftp = sftp_ssh.open_sftp()
# 执行ls操作
print(sftp.listdir())
# 其他操作示例
# sftp.put('本地文件路径', '远端存储路径')
# sftp.get('远端文件路径', '本地存储路径')

# 用完关闭连接
sftp.close()
sftp_ssh.close()
jump_ssh.close()

如果是Airflow场景,可以把跳板机、SFTP的连接信息都存在Airflow Connections里,读取后替换硬编码的参数即可。

方案2:跳板机执行批处理SFTP命令

如果不需要复杂操作,只是简单执行固定SFTP命令,可以直接把所有SFTP操作拼成一条命令在跳板机执行,不需要维护隧道:

def run_ssh():
    hook = SSHHook(ssh_conn_id='xyz').get_conn()
    # 把所有sftp操作通过管道传给sftp命令,-b参数指定从标准输入读取批处理命令
    sftp_cmd = """echo -e "ls\nget remote_file.txt\nquit" | sftp -o StrictHostKeyChecking=no -b - user@host.com << EOF
SFTP密码
EOF
"""
    stdin, stdout, stderr = hook.exec_command(sftp_cmd, get_pty=True)
    # 读取输出
    print(stdout.read().decode())
    print(stderr.read().decode())

注意这里加了get_pty=True分配伪终端,才能正确输入密码,批处理模式也能保证所有命令都在sftp会话内执行。

注意事项
  • 生产环境尽量不要用明文密码做SFTP认证,优先用SSH密钥对,把跳板机的公钥加到目标SFTP服务器的信任列表里,就不需要输入密码,也能避免明文密码泄露风险
  • Airflow场景下方案1更稳定,SFTP操作的报错可以直接在本地捕获排查,不需要解析跳板机的远端输出

内容的提问来源于stack exchange,提问作者Ash_s94

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 01:09:04