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

Python脚本打包目录并GPG加密后,解密时Tar文件损坏求助

问题分析与解决方案

我看到你遇到的问题是目录打包加密后,解密得到的tar文件损坏。仔细排查了你的代码,发现两个关键问题导致了这个情况:


问题1:手动关闭tar对象导致文件结构不完整

在dataTar函数里,你在with块中手动调用了tar.close(),但with语句的核心作用就是自动管理资源——当块结束时,会自动调用tar对象的close()方法,这个方法会完成tar文件的收尾工作(比如写入结束标记)。手动提前调用close()后,with块再次执行关闭操作,会直接破坏tar文件的结构,导致文件损坏。

问题2:错误的tar文件打开模式

你使用了'w|'模式创建tar文件,这个模式是流式写入模式,适用于从管道或标准输入读取数据并写入tar的场景。而直接创建本地tar文件时,应该使用普通的'w'模式,这样tarfile模块会正确处理文件的写入和结构完整性。


修改后的代码

下面是修复后的关键部分,以及完整的修正版本:

修复dataTar函数

def dataTar():
    if os.path.isfile(dataToEncrypt):
        return
    else:
        # 使用'w'模式替代'w|',并移除多余的tar.close()
        with tarfile.open(tarFile, 'w') as tar:
            tar.add(dataToEncrypt)

完整修正代码

#!/usr/bin/env python3
# Takes file in does symmetric encryption with the password you provide
# then adds it to a running IPFS(ipfs.io) instance.
#
import os
import argparse
import gnupg
import ipfsapi
import tarfile

# Parse command arguments
parser = argparse.ArgumentParser(description='Encrypt file/directory and add it to IPFS')
parser.add_argument('-i','--input', help='File.txt or Directory', required=True)
parser.add_argument('-p','--password', help='Password to encrypt with', required=True)
args = parser.parse_args()

# 设置临时GPG目录,避免默认目录的权限问题
gpg = gnupg.GPG(homedir='/tmp/gpg_temp')
gpg.encoding = 'utf-8'

# Get dataToEncrypt full path
dataToEncrypt = os.path.abspath(args.input)

# Setup tar filename to end with .zip
tarFile = f"{dataToEncrypt}.tar"
# Setup encrypted filename to end with .gpg
encryptedFile = f"{dataToEncrypt}.tar.gpg"

# Tell module where IPFS instance is located
api = ipfsapi.connect('127.0.0.1', 5001)

def dataTar():
    if os.path.isfile(dataToEncrypt):
        return
    else:
        # 使用普通写入模式'w',移除手动close
        with tarfile.open(tarFile, 'w') as tar:
            tar.add(dataToEncrypt)

def encryptFile():
    passphrase = args.password
    if os.path.isfile(dataToEncrypt):
        output_file = f"{dataToEncrypt}.gpg"
        with open(dataToEncrypt, 'rb') as f:
            status = gpg.encrypt(
                f,
                recipients=[],  # 对称加密不需要收件人,留空即可
                symmetric='AES256',
                passphrase=passphrase,
                armor=False,
                output=output_file
            )
    else:
        with open(tarFile, 'rb') as f:
            status = gpg.encrypt(
                f,
                recipients=[],
                symmetric='AES256',
                passphrase=passphrase,
                armor=False,
                output=encryptedFile
            )
    print('ok: ', status.ok)
    print('status: ', status.status)
    print('stderr: ', status.stderr)
    # 验证加密文件是否正常生成
    if os.path.exists(encryptedFile) and os.path.getsize(encryptedFile) > 0:
        print(f"加密文件 {encryptedFile} 创建成功")
    else:
        print("加密文件创建失败")

def ipfsFile(encryptedFile):
    # Add encrypted file to IPFS
    ipfsLoadedFile = api.add(encryptedFile, wrap_with_directory=True)
    # Return Hash of new IPFS File
    fullHash = ipfsLoadedFile[1]
    ipfsHash = fullHash['Hash']
    return ipfsHash

def delEncryptedFile(encryptedFile):
    try:
        os.remove(encryptedFile)
        # 同时清理临时tar文件
        if os.path.exists(tarFile):
            os.remove(tarFile)
    except Exception as e:
        print(f"Error: 无法删除文件 - {e}")

def main():
    dataTar()
    encryptFile()
    # 取消注释以下两行启用IPFS上传和文件清理
    # ipfs_hash = ipfsFile(encryptedFile)
    # print(f"File encrypted and added to IPFS with this hash: {ipfs_hash}")
    # delEncryptedFile(encryptedFile)

if __name__ == "__main__":
    main()

额外优化说明

  1. GPG目录调整:把GPG的homedir改成了/tmp/gpg_temp,避免使用用户默认的~/.gnupg可能遇到的权限问题,这个目录会自动创建(如果不存在)。
  2. 代码简化:删除了不必要的括号,使用f-string让字符串拼接更简洁易读。
  3. 加密参数规范:明确设置recipients=[],符合gnupg库对称加密的调用规范(之前的encrypt=False参数是多余的,对称加密模式下会自动忽略收件人)。
  4. 临时文件清理:在delEncryptedFile中增加了删除临时tar文件的逻辑,避免残留文件占用空间。

验证方法

修复后,你可以按以下步骤验证:

  1. 运行脚本加密目录:python3 your_script.py -i /path/to/your/dir -p your_password
  2. 解密生成的文件:gpg -d /path/to/your/dir.tar.gpg > test.tar
  3. 检查tar完整性:tar tvf test.tar,如果能正常列出目录内容,说明修复成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:49