参数列表太长:'/bin/sh'

参数列表太长:'/bin/sh'

我正在尝试通过 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

相关内容