2010-03-04 5 views
11

는 I는 명령 줄 도구를 실행하기 위해 서브 프로세스 모듈로부터 Popen 함수를 사용하고 :subprocess.Popen args 매개 변수의 최대 길이는 무엇입니까?

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) 

I가 사용하고있는 도구는 파일 그 다음 프로세스 목록 걸린다. 어떤 경우에는이 파일 목록이 매우 길 수 있습니다. 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에 대한 다음 문서를 발견했습니다 : Command prompt (Cmd. exe) command-line string limitation하지만 값에 하드 코드를 사용하고 싶지 않습니다. 오히려 런타임에 명령을 여러 호출로 나누기 위해 값을 얻고 싶습니다.

내가 Windows XP에서 파이썬 2.6을 사용하고 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을 여러 번 호출해도 괜찮습니다. args가 될 수있는 최대 길이를 얻는 일반적인 방법을 찾고 있으므로 각 실행을 위해 얼마나 많은 경로를 보낼지 알고 있습니다.

+0

당신이 인수를 제공 무엇의 예 값을 제공 할 수있다? –

+0

저는 파티에 꽤 늦었습니다. 그러나 PATH 환경 변수가 많은 항목을 추가 한 후에 너무 길어 져서 같은 오류가 발생했다는 것을 추가하고 싶습니다. – RedX

답변

9

shell = False를 전달하면 Cmd.exe가 재생되지 않습니다.

Windows에서 하위 프로세스는 Win32 API의 CreateProcess 함수를 사용하여 새 프로세스를 만듭니다. 이 함수의 documentation은 두 번째 인수 (subprocess.list2cmdline에 의해 빌드 됨)가 유니 코드 종료 널 문자를 포함하여 최대 길이가 32,768 자임을 나타냅니다. lpApplicationName이 NULL이면 lpCommandLine의 모듈 이름 부분은 MAX_PATH 문자로 제한됩니다.

예를 들어, 실행 파일 (args [0])의 값을 제공하고 첫 번째 매개 변수에 args를 사용하는 것이 좋습니다. CreateProcess 문서와 서브 프로세스 모듈 소스 코드를 읽었다면 문제가 해결 될 것입니다.

[편집 : 제거 된 인수 [1 :] 윈도우 머신 및 테스트에 내 손을 점점 후 비트]

+0

args [1 :]을 첫 번째 매개 변수로 사용하는 것과 관련된 제안을 따르는 지 잘 모르겠습니다. 코드 예제로 내 질문을 업데이트했습니다. +1 링크 및 CreateProcess에 대한 팁 –

+0

나는 이것을 시도했지만 여전히 한계를 넘기고있다 : subprocess.Popen (cmd [1 :] + paths, executable = cmd [0], stdout = subprocess.PIPE). 지금은 32000을 명령 길이의 제한으로 사용하고 여러 번 명령을 호출하고 모든 출력을 수집합니다. 나는 32000 하드 코딩 된 수 있지만 환경에서 그 가치를 얻을 수 싶습니다. –

+0

필자가 인용 한 문서에서 언급 한 것처럼 32768 제한은 CreateProcess 프리미티브 (16 비트 부호있는 정수의 상한값, 즉 2 ** 15)에 하드 코딩되어 있습니다. 명령 행을 작성할 때 list2cmd가 따옴표와 공백을 추가하므로 합계 ([args의 a len (a)])가 2 ** 15에 도달하기 전에 제한을 초과합니다. 와일드 카드를 사용하여 실행 파일에 인수를 전달하는 방법이 없습니까?(와일드 카드는 일반적으로 윈도우에서 실행 파일로 처리됩니다.) –

관련 문제