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

Python脚本无法修改7z压缩包内文件名,但Bash命令可正常执行

7z压缩包内长文件名重命名问题:Python subprocess调用失败但Bash直接执行成功

我正在编写Python脚本处理7z压缩包,流程是解压后重新压缩为zip格式以保持一致性。部分7z包内的文件名过长,导致解压时报错,因此需要先重命名这些长文件名。

遇到的核心问题:在Bash中直接执行命令7z rn -pSOMEPASSWORD -y archive.7z oldfilename newfilename可以成功重命名,但通过Python的subprocess调用相同命令时,命令静默失败,文件名未发生更改。

扫描过长文件名的代码

# scan list of files and bucket all of the bad filenames
with SevenZipFile(fpath, password=password) as f:
    for filename in f.namelist():
        segments = filename.split("/")
        mname = segments[-1]

        if len(mname.encode()) > MAX_FILENAME_LENGTH:
            long_filenames.append(filename)

重命名文件的代码

with SevenZipFile(fpath, password=password) as f:
    for filename in long_filenames:
        checksum = crc32_checksum(filename.encode())

        if checksum:
            segments = filename.split("/")
            mname = segments[-1]
            root, ext = os.path.splitext(mname)

            zdir = "/".join(segments[:-1])
            zpath = os.path.join(zdir, checksum + ext)

            f.rename(filename, zpath)

检查重命名结果的代码

with SevenZipFile(fpath, password=password) as f:
    long_filenames.clear()

    for filename in f.namelist():
        segments = filename.split("/")
        mname = segments[-1]

        if len(mname.encode()) > MAX_FILENAME_LENGTH:
            long_filenames.append(filename)

    if long_filenames:
        raise SevenZipError("Files not renamed.")

SevenZipFile类核心实现代码

def _run(self, cmd: str, switches: list[str] | None = None, args: list[str] | None = None) -> str:
    if not switches:
        switches = []
    if not args:
        args = []

    # blank password is skipped for archives with no password, but allows
    # archives with passwords to error instead of wait for user input.
    if self.password:
        switches.append(f"-p{self.password}")
    else:
        switches.append("-p")
    switches.append("-y") # assume Yes on all queries

    sh = [self.sh, cmd] + switches + [self.path] + args
    result = subprocess.run(sh, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

    if result.returncode != 0:
        raise SevenZipError(f"7zip failed: {result.stderr}")

    return result.stdout


def rename(self, srcfilename: str, destfilename: str):
    self._run("rn", [], [srcfilename, destfilename])

已尝试的无效操作

  • 给subprocess显式指定utf-8编码
  • 设置Python运行环境的LC_ALL为utf-8

推测原因

怀疑Python与7z之间存在编码不兼容问题,导致包含Unicode字符(如文件名中的emoji)的文件名在传递过程中损坏,但Python日志中emoji可以正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:29:53