Python调用subprocess执行tar报错Argument list too long求助
问题原因
Argument list too long报错是操作系统内核限制了命令行参数及环境变量的总长度,Ubuntu 20.04默认该限制(ARG_MAX)约为2MB,文件数量过多时拼接的命令总长度超出阈值就会触发报错。你添加的ulimit -s调整的是进程栈大小,和命令行参数长度限制无关,因此不会生效。另外你使用的字符串拼接命令+shell=True的写法还存在shell注入风险,也不推荐使用。
可行解决方案
方案1:通过标准输入向tar传递文件列表(最推荐)
tar原生支持-T -参数,直接从标准输入读取待打包的文件路径,完全规避参数长度限制,同时不需要开启shell,性能和安全性都最优。
import subprocess # 按行拼接文件列表,路径规则和你原有逻辑保持一致即可 file_input = '\n'.join(file_list).encode('utf-8') subprocess.run( ['tar', '-cz', '-f', output_file, '-T', '-'], cwd=source_dir, input=file_input, check=True )
方案2:通过临时文件传递文件列表
如果你不想通过标准输入传参,可以先把文件列表写入临时文件再传给tar的-T参数:
import subprocess import tempfile import os # 生成临时文件存储文件列表 with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as f: f.write('\n'.join(file_list)) temp_path = f.name try: subprocess.run( ['tar', '-cz', '-f', output_file, '-T', temp_path], cwd=source_dir, check=True ) finally: # 执行完成后删除临时文件 os.unlink(temp_path)
方案3:使用Python标准库tarfile实现打包
完全不依赖外部tar命令,直接用Python内置模块完成打包,从根源上避免参数长度问题:
import tarfile import os with tarfile.open(output_file, 'w:gz') as tar: for file in file_list: # arcname参数控制打包后文件的相对路径,和原有路径保持一致 tar.add(os.path.join(source_dir, file), arcname=file)
内容的提问来源于stack exchange,提问作者usert4jju7
相关产品推荐
相关产品推荐

