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

如何用Python原生实现本地与远端文件传输并获取进程实时状态

问题根因

你之前的写法失败主要有两个核心问题:

  • 第一种写法没有给subprocess.Popen加shell=True参数,默认情况下subprocess不会解析shell语法(包括管道符、引号、&&逻辑符都不会处理),同时你给出的命令字符串还遗漏了末尾的闭合双引号
  • 第二种写法用列表传参时错误地把后续管道逻辑都当成了tar的参数,列表传参要求每个命令参数单独作为列表元素,且默认不会解析管道等shell语法,完全无法实现你要的跨进程管道传输逻辑

实现方案

方案1:直接启用shell解析(最简实现)

如果你能保证命令中的路径、地址等参数都是可控的,不会有注入风险,直接加shell=True即可完美适配你原来的shell命令逻辑,同时可以拿到进程状态:

import subprocess

cmd = 'tar zcf - somefolder/ | ssh user@server "cd /path/to/remote && tar zxf -"'
# 启用shell解析管道、引号等语法
p = subprocess.Popen(cmd, shell=True)

# 获取实时状态示例:
while True:
    exit_code = p.poll()
    if exit_code is None:
        print("进程仍在运行")
        # 这里可以自定义轮询间隔
        import time
        time.sleep(1)
    else:
        print(f"进程执行完成,退出码:{exit_code}")
        break

你也可以用os.waitpid(p.pid, 0)来阻塞等待进程结束,和你之前的需求完全兼容。

方案2:无shell模式手动拼接管道(更安全)

如果担心shell注入风险,可以不用启用shell解析,手动创建本地tar进程和远端ssh进程,把两个进程的输入输出流对接,逻辑更可控:

import subprocess

# 本地打包进程
tar_proc = subprocess.Popen(
    ["tar", "zcf", "-", "somefolder/"],
    stdout=subprocess.PIPE
)
# 远端解压进程
ssh_proc = subprocess.Popen(
    ["ssh", "user@server", "cd /path/to/remote && tar zxf -"],
    stdin=tar_proc.stdout
)
# 关闭tar进程的stdout副本,避免IO阻塞
tar_proc.stdout.close()

# 多进程状态获取
while True:
    tar_exit = tar_proc.poll()
    ssh_exit = ssh_proc.poll()
    if tar_exit is not None and ssh_exit is not None:
        print(f"打包进程退出码:{tar_exit},远端解压进程退出码:{ssh_exit}")
        break
    import time
    time.sleep(1)

两种方案都不需要引入第三方库,完全基于Python标准库实现。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:24:01