Подтвердить что ты не робот

Что такое subprocess.Popen max length параметра args?

Я использую Popen из модуля подпроцесса для выполнения инструмента командной строки:

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? При большом количестве файлов, передаваемых в инструмент, я получаю следующую ошибку:

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:\python26\lib\subprocess.py", line 621, in __init__
    errread, errwrite)
  File "c:\python26\lib\subprocess.py", line 830, in _execute_child
    startupinfo)
WindowsError: [Error 206] The filename or extension is too long

Есть ли общий способ найти эту максимальную длину? Я нашел следующую статью о msdn: ограничение строки командной строки командной строки (Cmd. Exe), но я не хочу жестко кодировать в стоимость. Я предпочел бы получить значение во время выполнения, чтобы разбить команду на несколько вызовов.

Я использую Python 2.6 на 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 обычно представляет собой очень длинный путь к файлу И их несколько тысяч.

Я не против разбить команду на несколько вызовов process_file.exe. Я ищу общий способ получить максимальную длину, которая может быть аргументами, поэтому я знаю, сколько путей для отправки для каждого прогона.

4b9b3361

Ответ 1

Если вы передаете shell = False, то Cmd.exe не входит в игру.

В окнах подпроцесс будет использовать функцию CreateProcess из Win32 API для создания нового процесса. В документации для этой функции указано, что второй аргумент (который строит по subprocess.list2cmdline) имеет максимальную длину 32 768 символов, включая завершение Unicode null знак. Если lpApplicationName NULL, часть имени модуля lpCommandLine ограничена символами MAX_PATH.

Учитывая ваш пример, я предлагаю предоставить значение для исполняемого файла (args [0]) и использовать аргументы для первого параметра. Если мое чтение документации CreateProcess и исходного кода модуля подпроцесса верное, это должно решить вашу проблему.

[edit: удалил бит args [1:] после того, как я получил доступ к машине Windows и тестированию)