我正在尝试通过 Python 调用来调用tar
命令subprocess
。我面临的挑战是传递了很多文件,tar
导致命令抛出错误Argument list too long: '/bin/sh'
我正在运行的命令如下
subprocess.call(f"ulimit -s 999999999; tar -cz -f {output_file} {file_list}", cwd=source_dir, shell=True)
为了尝试克服该错误,我添加了ulimit
这似乎没有帮助。
请我得到帮助来解决这个问题。
答案1
将文件名作为巨型字符串的一部分传递是总是这是一个坏主意(一旦单个文件名中存在单个空格,它就会立即中断)。
相反,使用允许您提供参数列表作为列表的接口;在几乎所有情况下,该shell=True
选项都是一个坏主意,尤其是在这里(假设其中有一个文件被调用something; rm -rf ..
,此命令将删除您绝对不想删除的内容......)。
但作为CAS 说,您确实应该使用tar
从文本文件读取文件名的能力。
tar
但更好的是:根本不调用外部。只需使用Pythontarfile
模块,是的,你的 Python 附带了这个模块。那么你就没有这些问题了!
稍微修改一下上面模块文档中的最短示例:
import tarfile
…
tar = tarfile.open(output_file, "w:gz")
for filename in files_in_an_actual_list:
tar.add(filename)
tar.close()
答案2
如果您使用的是 GNU tar
,则可以将 tar 存档中所需的文件列表写入文本文件,然后使用 GNU tar 的-T
(又名--files-from
)选项。
从man tar
:
-T
,--files-from=FILE
获取要从 FILE 中提取或创建的名称。
除非另有指定,否则 FILE 必须包含由 ASCII LF 分隔的名称列表(即每行一个名称)。读取的名称的处理方式与命令行参数相同。它们经过引号删除和分词,并且任何以 a 开头的字符串都
-
被处理为 tar 命令行选项。如果不希望出现此行为,可以使用该
--verbatim-files-from
选项将其关闭。该
--null
选项指示 tar FILE 中的名称由 ASCII NUL 字符而不是 LF 分隔。如果列表是由find
(1)谓词生成的,则很有用-print0
。