简体   繁体   English

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

[英]Passing very long list as sys.argv (pvpython to python)

Error: 错误:

OSError: [Errno 7] Argument list too long OSError:[Errno 7]参数列表太长

History: 历史:

Running a script on pvpython (vtk); pvpython上运行脚本(vtk); however on older distributions pvpython < 5.0, the matplotlib modules are obsolete, thus making the use of that module not possible. 但是在较旧的发行版pvpython <5.0上,matplotlib模块已经过时,因此无法使用该模块。 To overcome this, another .py is used and the arguments passed in the terminal using subprocess as shown below and run on python but since the information passed is large, the above error is met. 为了解决这个问题,使用了另一个.py并且终端使用subprocess在终端中传递,如下所示并在python上运行,但由于传递的信息很大,因此满足上述错误。

The problematic code is: 有问题的代码是:

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 and 7 are extremely lengthy (882770, 879326) characters each, as they are lists. argv 6和7每个字符都非常冗长(882770,879326),因为它们是列表。

An alternate solution could be to pass the list into a temp file and load those in to python module. 另一种解决方案是将列表传递给临时文件并将其加载到python模块中。 But I am trying to save on write and load time. 但我试图节省写入和加载时间。

Thus am looking for a way to pass large arguments in terminal or how to pass arguments two environments, in this case pvpython and python. 因此,我正在寻找一种方法来传递终端中的大型参数或如何传递两个环境的参数,在本例中是pvpython和python。

An immediately visible possible cause is that you are not using proper quoting and escaping according to your system shell's syntax when constructing the command line. 一个直接可见的可能原因是,在构造命令行时,根据系统shell的语法,您没有使用正确的引用和转义。 So if your argument's string representation has spaces or special shell characters, it will be misinterpreted as many arguments (or worse). 因此,如果你的参数的字符串表示有空格或特殊的shell字符,那么它将被误解为许多参数(或更糟)。

So, don't use shell=True (which is not recommended for use specifically for this reason!) and invoke your program via a proper argument list: 所以, 不要使用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)

Besides, and since command line passing is OS-specific (eg in Windows, your array will be combined into a single line under the hood anyway because that's how CreateProcess requires the command line to be passed) and individual command line arguments are also subject to length limits , a better solution is to pass arbitrarily long data by means other than the command line. 此外,由于命令行传递是特定于操作系统的(例如在Windows中,无论如何,您的数组将被组合成一个单独的行,因为这是CreateProcess需要传递命令行的方式),并且各个命令行参数也受制于长度限制更好的解决方案是通过命令行以外的方式传递任意长的数据。

There are the following ways to pass information to a child process: 有以下方法将信息传递给子进程:

  • Command line 命令行
  • files (since filesystem is a shared resource, with due protection considerations from other processes ) 文件(因为文件系统是共享资源, 其他进程需要考虑到保护
  • IPC (pipes incl. standard streams, shared memory, sockets etc.) IPC(管道包括标准流,共享内存,插槽等)
  • things inherited via fork() : 通过fork()继承的东西:
    • memory snapshot (only applies if the child is running the same program) 内存快照(仅在子节点运行相同程序时适用)
    • descriptors (standard streams also fall here; note that Python intentionally marks file descriptors other than standard streams non-inheritable by default) 描述符(标准流也在这里;请注意,Python默认标记除标准流之外的文件描述符不可继承)
    • environment variables 环境变量

As you can see, command line parameters are far from being the only way. 如您所见,命令行参数远非唯一的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM