将很长的列表作为sys.argv传递(从pvpython到python)

时间:2019-04-17 15:50:55

标签: python python-2.7 subprocess argv pvpython

错误:

  

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

历史:

pvpython (vtk)上运行脚本;但是,在较旧的发行版pvpython <5.0上,matplotlib模块已过时,因此无法使用该模块。为了克服这个问题,使用了另一个.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)传递参数。

1 个答案:

答案 0 :(得分:0)

一个直接可见的可能原因是,在构造命令行时,没有按照系统外壳程序的语法使用正确的引号和转义符。因此,如果参数的字符串表示形式包含空格或特殊的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要求传递命令行的方式),并且{ {3}},更好的解决方案是通过命令行以外的方式传递任意长的数据。

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

  • 命令行
  • 文件(由于文件系统是共享资源,individual command line arguments are also subject to length limits
  • IPC(包括标准流,共享内存,套接字等的管道)
  • 通过fork()继承的
  • 事物:
    • 内存快照(仅在子代运行相同程序时适用)
    • 描述符(标准流也位于此处;请注意,Python故意标记了默认情况下不可继承的标准流以外的文件描述符)
    • 环境变量

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