2009-02-09 4 views
3

msi 설치 프로그램을 자동 모드로 실행하고 특정 파일에 로그를 캐싱 중입니다. 다음 명령을 실행해야합니다.subprocess.Popen error

C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"

내가 사용 :

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0] 

그러나이 동작을 인식하지 못하는 명령을 실행하고 선택한 잘못된 옵션에 대한 오류를 제공 할 수 있습니다. 나는 십자가 검증을했고이 명령은이 방법으로 만 작동한다는 것을 알았습니다.

답변

8

문제는 매우 미묘합니다.

프로그램을 직접 실행하고 있습니다. 그것은 가져옵니다

argv[0] = "C:\Program Files\ My Installer\Setup.exe" 
argv[1] = /s /v "/qn /lv %TEMP%\log_silent.log" 

그것이 있어야 반면 :

argv[1] = "/s" 
argv[2] = "/v" 
argv[3] = "/qn" 
argv[4] = "/lv %TEMP%\log_silent.log" 

즉, 5 인자가 아닌 2 개 인자를 받아야합니다.

또한 %TEMP%은 프로그램에 직접 알려지지 않았습니다. 쉘을 호출

  1. :

    2이 개 문제를 해결하는 방법이 있습니다.

    p = subprocess.Popen('C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"', shell=True) 
    output = p.communicate()[0] 
    
  2. 직접 프로그램 (더 안전한)

    s = ['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'] 
    safes = [os.path.expandvars(p) for p in argument_string] 
    p = subprocess.Popen(safes[0], safes[1:]) 
    output = p.communicate()[0] 
    
+1

또한 "C : \ Program Files \ My Installer \ Setup.exe"는 r "C : \ Program Files \ My Installer \ Setup.exe"여야합니다. 그 중 하나를 두 배로 늘리거나 문자열을 문자열로 사용해야합니다. –

2

문제는 효과적으로 하나의 인수로 Setup.exe를 제공한다는 것입니다. 쉘과 관련하여 생각하지 마십시오. 인수로 전달한 문자열이 더 이상 공간에서 분리되지 않습니다. 이것이 당신의 의무입니다! 당신이 "/ QN/LV % TEMP % \ log_silent.log"하나 개의 인수해야한다,이 사용하는 것이 절대적으로 확신하는 경우

그래서, 그렇지 않으면

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn /lv %TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0] 

을 (나는이 일이 올 것 같아요)이 사용

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn', '/lv', '%TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0] 
+0

도왔다. – kingpin

+0

인용문이 필요합니다. 이유를 모르겠다. 심지어 스위치 v가 반복됩니다. I – kingpin

0

는 자신의 캐릭터에 각 인수를 넣어보십시오() 읽기 쉽도록 포맷 :

cmd = ['C:\Program Files\ My Installer\Setup.exe', 
     '/s', 
     '/v', 
     '"/qn', 
     '/lv', 
     '%TEMP%\log_silent.log"'] 

subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0] 

그래도 그 큰 따옴표는 내게 맞는 곳에서 보지 않는다고 말해야합니다.

0

전화 당신은 말했다 :

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0] 

가와 (디렉토리 이름 정말 "내 설치"가 앞 공간)?

또한 일반적으로 경로 사양에 슬래시를 사용해야합니다.파이썬은 (심지어 Windows에서도) 완벽하게 처리해야하며 파이썬이 백 슬래시를 이스케이프 문자로 해석하는 데 문제가 발생하지 않도록해야합니다.

(예 :

>>> s = 'c:\program files\norton antivirus' 
>>> print s 
c:\program files 
orton antivirus 

)

공간에 의해 구분되는 각 인수를 갖는

+0

선행 공백이 없습니다. – kingpin

+0

... 그러면 경로에 선행 공백이있는 코드는 명백한 오류의 원인입니다. –

관련 문제