args 参数的 subprocess.Popen 最大长度是多少?

2022-01-18 00:00:00 python shell subprocess popen

问题描述

我正在使用子进程中的 Popen 函数执行命令行工具的模块:

I am using Popen function from the subprocess module to execute a command line tool:

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

我正在使用的工具需要一个文件列表,然后它会处理这些文件.在某些情况下,此文件列表可能很长.有没有办法找到 args 参数的最大长度?将大量文件传递给该工具时,我收到以下错误:

The tool I am using takes a list of files that it then processes. In some cases, this list of files can be very long. Is there a way to find the max length that the args parameter can be? With a large number of files being passed to the tool, I am getting the following error:

Traceback (most recent call last):
  File "dump_output_sopuids.py", line 68, in <module>
    uid_map = create_sopuid_to_path_dict_dcmdump(dicom_files)
  File "dump_output_sopuids.py", line 41, in create_sopuid_to_path_dict_dcmdump
    dcmdump_output = subprocess.Popen(cmd,stdout=subprocess.PIPE).communicate(0)[0]
  File "c:python26libsubprocess.py", line 621, in __init__
    errread, errwrite)
  File "c:python26libsubprocess.py", line 830, in _execute_child
    startupinfo)
WindowsError: [Error 206] The filename or extension is too long

有没有找到这个最大长度的通用方法?我在 msdn 上找到了以下文章:命令提示符 (Cmd.exe) 命令行字符串限制 但是我不想在值中硬编码.我宁愿在运行时获取值以将命令分解为多个调用.

Is there a general way to find this max length? I found the following article on msdn: Command prompt (Cmd. exe) command-line string limitation but I don't want to hard code in the value. I would rather get the value at run time to break up the command into multiple calls.

我在 Windows XP 64 上使用 Python 2.6.

I am using Python 2.6 on Windows XP 64.

添加代码示例

paths = ['file1.dat','file2.dat',...,'fileX.dat']
cmd = ['process_file.exe','+p'] + paths
cmd_output = subprocess.Popen(cmd,stdout=subprocess.PIPE).communicate(0)[0]

出现问题是因为 paths 列表中的每个实际条目通常是一个非常长的文件路径并且有几千个.

The problem occurs because each actual entry in the paths list is usually a very long file path AND there are several thousand of them.

我不介意将命令分解为对 process_file.exe 的多个调用.我正在寻找一种通用方法来获取 args 的最大长度,以便我知道每次运行要发送多少条路径.

I don't mind breaking up the command into multiple calls to process_file.exe. I am looking for a general way to get the max length that args can be so I know how many paths to send in for each run.


解决方案

如果你传递 shell=False,那么 Cmd.exe 就不会起作用.

If you're passing shell=False, then Cmd.exe does not come into play.

在 Windows 上,子进程将使用 Win32 API 中的 CreateProcess 函数来创建新进程.该函数的文档指出第二个参数(由 subprocess.list2cmdline 构建)的最大长度为 32,768 个字符,包括 Unicode 终止空字符.如果 lpApplicationName 为 NULL,则 lpCommandLine 的模块名称部分仅限于 MAX_PATH 字符.

On windows, subprocess will use the CreateProcess function from Win32 API to create the new process. The documentation for this function states that the second argument (which is build by subprocess.list2cmdline) has a max length of 32,768 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

鉴于您的示例,我建议为可执行文件 (args[0]) 提供一个值,并将 args 用作第一个参数.如果我对 CreateProcess 文档和子流程模块源代码的阅读是正确的,那么这应该可以解决您的问题.

Given your example, I suggest providing a value for executable (args[0]) and using args for the first parameter. If my reading of the CreateProcess documentation and of the subprocess module source code is correct, this should solve your problem.

位]

相关文章