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

如何用Python tarfile处理subprocess输出的tar归档流?

问题:用Python的subprocess和tarfile实现tar管道功能

我有一个类似ssh的nomad alloc exec命令,可在远端执行tar命令并获取其stdout输出。想要实现Shell中ssh server tar cf - file1 file2 | tar xf - -C destinationdir的tar管道功能:用subprocess作为管道左侧,右侧使用tarfile而非额外的subprocess或Shell。

尝试了以下代码:

import os
import subprocess
import tarfile

os.system("echo 123 > /tmp/1 ; mkdir -p /tmp/dir")
sourcefile = "/tmp/1"
destinationdir = "/tmp/dir"
with subprocess.Popen([*"tar -cf - --".split(), sourcefile], stdout=subprocess.PIPE) as pp:
    with tarfile.open(fileobj=pp.stdout) as tf:
        tf.extractall(destinationdir)

但执行时报错:

$ python3 ./test.py 
tar: Removing leading `/' from member names
Traceback (most recent call last):
  File "/dev/shm/.1000.home.tmp.dir/./test.py", line 9, in <module>
    with tarfile.open(fileobj=pp.stdout) as tf:
  File "/usr/lib/python3.10/tarfile.py", line 1630, in open
    saved_pos = fileobj.tell()
OSError: [Errno 29] Illegal seek

原因是tarfile默认会尝试对输入文件对象执行seek/tell操作,但subprocess的stdout管道是单向的、不可定位的流,不支持这些操作。


解决方案

使用tarfile的流式读取模式mode='r|*',这个模式专门用于处理不可seek的输入流,不需要定位文件指针。修改后的代码如下:

import os
import subprocess
import tarfile

os.system("echo 123 > /tmp/1 ; mkdir -p /tmp/dir")
sourcefile = "/tmp/1"
destinationdir = "/tmp/dir"

# 启动tar命令生成流式归档
with subprocess.Popen(
    ["tar", "-cf", "-", "--", sourcefile],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE  # 可选:捕获tar的stderr输出,避免干扰终端
) as pp:
    # 使用流式模式打开tar归档,不需要seek操作
    with tarfile.open(fileobj=pp.stdout, mode='r|*') as tf:
        tf.extractall(destinationdir)
    
    # 可选:检查tar命令是否正常退出
    if pp.returncode != 0:
        stderr = pp.stderr.read().decode()
        raise RuntimeError(f"tar命令执行失败: {stderr}")

关键修改点:

  • 将tarfile.open()的mode参数指定为'r|*',这是tarfile的流式读取模式,会逐块处理输入,不需要对文件对象执行seek操作。
  • 可选:添加stderr=subprocess.PIPE捕获tar命令的错误输出,方便排查问题。
  • 可选:检查subprocess的返回码,确保远端tar命令执行正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 15:38:17