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

use*_*ju7 0 python bash python-3.x

我正在尝试通过 Python 调用来调用tar 命令。subprocess我面临的挑战是传递了很多文件,tar导致命令抛出错误Argument list too long: '/bin/sh'

我正在运行的命令如下

subprocess.call(f"ulimit -s 99999999; tar -cz -f {output_file} {file_list}", cwd=source_dir, shell=True)
Run Code Online (Sandbox Code Playgroud)

为了尝试克服该错误,我添加了ulimit这似乎没有帮助。我运行的操作系统是 Ubuntu-20.04 & Pyhon 版本是 3.8

请我得到帮助来解决这个问题。

tri*_*eee 5

ulimit没有做任何事情来提升内核常量,ARG_MAX这就是你在这里遇到的。事实上,增加它的唯一方法通常是重新编译内核。

如果您tar支持--files-from -,请使用它。

subprocess.check_call(
    ['tar', '-cz', '-f', output_file, '--files-from', '-'],
    input='\n'.join(file_list), cwd=source_dir)
Run Code Online (Sandbox Code Playgroud)

显然,我对内容做出了假设file_list(特别是,如果您的文件名称包含换行符,这将会中断)。另请注意我如何避免shell=True将命令作为字符串列表传递。

当然,对于这种用例来说,更好的解决方案是使用Pythontarfile模块来创建tar文件;这完全避免了跨进程边界传输文件名列表的需要。

import tarfile

with tarfile.open(output_file, "x:gz") as tar:
    for name in file_list:
        tar.add(name)
Run Code Online (Sandbox Code Playgroud)

"x:gz"如果文件已经存在(用于"w:gz"简单覆盖),创建模式会触发异常。