【问题标题】:`Argument list too long: '/bin/sh'``参数列表太长:'/bin/sh'`
【发布时间】:2022-01-07 02:40:38
【问题描述】:

我正在尝试通过来自 Python 的 subprocess 调用调用 tar 命令。我面临的挑战是有很多文件传递给 tar,这导致命令抛出错误 @987654326 @

我正在运行的命令如下

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

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

请帮我解决这个问题。

【问题讨论】:

  • 尝试间接级别并将列表放入文件中? stackoverflow.com/questions/8033857/…(可能称为mlylist.txt,并在tar 命令中添加-T mylist.txt
  • 你无法控制命令行的最大长度,除非你重新编译源码。顺便说一句,ulimit -s 设置最大堆栈大小。
  • 除了医生爱的聪明想法:你能不能把文件复制到某个临时目录(之后你会删除)?然后你只需将目录名称传递给tar
  • 请不要跨堆栈多发帖 (unix.stackexchange.com/q/679620/117549)

标签: python python-3.x bash


【解决方案1】:

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

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

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

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

当然,对于这个用例,更好的解决方案是使用the Python tarfile module 创建tar 文件;这完全避免了跨进程边界传输文件名列表的需要。

import tarfile

with tarfile.open(output_file, "x:gz") as tar:
    for name in file_list:
        tar.add(name)

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

【讨论】:

    猜你喜欢
    • 2020-05-26
    • 1970-01-01
    • 2014-08-30
    • 2015-04-27
    • 2019-02-22
    • 2021-03-28
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多