【问题标题】:Passing very long list as sys.argv (pvpython to python)将很长的列表作为 sys.argv 传递(pvpython 到 python)
【发布时间】:2019-04-17 15:50:54
【问题描述】:

错误:

OSError: [Errno 7] 参数列表太长

历史:

pvpython (vtk) 上运行脚本;但是在较旧的发行版 pvpython .py 并使用subprocess 在终端中传递参数,如下所示并在 python 上运行,但由于传递的信息很大,遇到上述错误。

有问题的代码是:

import subprocess
command = ("python illustrations.py %s %s %s %s %s %s %s %s %s %s" % (str(post_processing), str(width), str(height), str(len(new_overall_lines)), str(reset_scale), str(str_rose_angle), str(str_damage), str(fname), str(fname1), str("ax=None")))
subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)

argv 6 和 7 都是非常长的字符(882770、879326),因为它们是列表。

另一种解决方案是将列表传递到临时文件中,然后将它们加载到 python 模块中。但我试图节省写入和加载时间。

因此我正在寻找一种在终端中传递大参数的方法,或者如何在两个环境中传递参数,在本例中为 pvpython 和 python。

【问题讨论】:

  • 我会将该数据存储在一个文件中并传递文件名
  • 升级pvpython不是一个选项吗?
  • 忽略 shell=True 并检查你 getconf ARG_MAXarg_max val
  • 如果你只有一个大列表,你可以让你尝试运行的 Python 程序从sys.stdin 读取并将列表输入。但如果你有多个大列表,我认为没有将它们保存到临时文件并传递这些文件的路径的任何方式。
  • 使用picklejson 保存到文件,然后读取。只需几行代码,也不会花费太多时间。将圣经大小的列表作为命令行参数传递可能不是一个好主意。

标签: python python-2.7 subprocess argv pvpython


【解决方案1】:

一个立即可见的可能原因是您在构建命令行时没有根据系统 shell 的语法使用正确的引用和转义。因此,如果您的参数的字符串表示形式包含空格或特殊的 shell 字符,它将被误解为多个参数(或更糟)。

所以,不要使用shell=True(不建议专门为此使用!)并通过适当的参数列表调用您的程序:

command = ["python", "illustrations.py"] +
          [str(v) for v in post_processing, width, height,
                            len(new_overall_lines), reset_scale,
                            str_rose_angle, str_damage,
                            fname, fname1] +
          ["ax=None"]

subprocess.Popen(command, stdout=subprocess.PIPE)

此外,由于命令行传递是特定于操作系统的(例如,在 Windows 中,无论如何,您的数组都会在后台合并为一行,因为这就是 CreateProcess 要求传递命令行的方式)和 individual command line arguments are also subject to length limits , 更好的解决方案是通过命令行以外的方式传递任意长的数据。

将信息传递给子进程有以下几种方式:

  • 命令行
  • 文件(因为文件系统是共享资源,with due protection considerations from other processes
  • IPC(管道,包括标准流、共享内存、套接字等)
  • 通过fork()继承的东西:
    • 内存快照(仅在孩子运行相同程序时适用)
    • 描述符(标准流也属于这里;请注意,Python 有意将标准流以外的文件描述符标记为默认不可继承)
    • 环境变量

如您所见,命令行参数远不是唯一的方法。

【讨论】:

    猜你喜欢
    • 2021-06-18
    • 1970-01-01
    • 2017-10-30
    • 2011-01-20
    • 2016-12-26
    • 2021-06-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多