2014-07-11 3 views
1

저는 csv 파일에서 모든 입력 이름과 출력 이름을 최적화하고 정렬하기위한 많은 이미지가 있습니다. 이전에는 AWK를 사용하여 이러한 종류의 작업을 수행했지만 지금은 .Popen 메서드로 파이썬으로 전환하는 것을 선호합니다. 서브 프로세스의 다중 변수. % dict()가있는 팝업 %

import subprocess 
import shlex 
cmdc2d='c2d %(inname)s -clip 1% 99% -type short -stretch 1% 99% 0 255 -o %(outname)s' 
argscmd=shlex.split(cmdc2d) 
subprocess.Popen(argscmd%dict(inname='test1.png',outname='test1-2.png')) 

출력

나에게

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for %: 'list' and 'dict' 

가 어떻게이 Ponpen []에 그 모든 변수를 전달할 수있는 오류를했다?

미리 감사드립니다.

답변

0

두 가지 문제가 있습니다. 먼저 문자열을 분할하기 전에 보간을 수행해야합니다. 당신이 보간하기 전에 명령 문자열을 분할하기 때문에,

argscmd%dict(inname='test1.png',outname='test1-2.png') 

에서 %의 첫 번째 피연산자는 목록이며, %는 목록과 딕셔너리에 대한 정의 작동하지 않습니다. %의 첫 번째 피연산자가 문자열이어야합니다. 같은 시도 :

import subprocess 
import shlex 
cmdc2d='c2d %(inname)s -clip 1% 99% -type short -stretch 1% 99% 0 255 -o %(outname)s' 
argscmd=shlex.split(cmdc2d % dict(inname='test1.png',outname='test1-2.png')) 
subprocess.Popen(argscmd) 

둘째, 당신은 %의 문자로 구성되어 % 문자를 탈출해야합니다. 당신이 원하는 것 :

import subprocess 
import shlex 
cmdc2d='c2d %(inname)s -clip 1%% 99%% -type short -stretch 1%% 99%% 0 255 -o %(outname)s' 
argscmd=shlex.split(cmdc2d % dict(inname='test1.png',outname='test1-2.png')) 
subprocess.Popen(argscmd) 
+0

감사합니다. 그러면 스크립트로 csv를 가져갈 것입니다. – user3817800

+0

@ user3817800 :'inname' 또는'outname'에 공백이 있으면'shlex.split()'이 깨집니다. Popen()을 읽기 시작 했으므로 [목록 대신 직접 목록을 만들 수 있습니다.] (http://stackoverflow.com/a/25163739/4279) – jfs

0

나는에 @Alp 답을 바꿀 것 : 이것은 당신이는 popen을 닫고 또한 입력을 읽을 수

subprocess.Popen(argscmd, shell=True, stdout=subprocess.PIPE, preexec_fn=os.setsid)

. os.setsid는 처음부터 목록으로 명령을 구성, inname, outname 파일 이름에 공백 (또는 다른 특수 문자)를 허용하려면 C

https://docs.python.org/2/library/subprocess.html#subprocess.PIPE

https://docs.python.org/2/library/os.html#os.setsid

+0

거의 모든 사람이 shell = True가 안전하지 않다고 말했습니다. 나는이 순간에 그것을 사용하는 것을 주저한다. .. 미안. – user3817800

+0

고마워! 나는 그것을 염두에 두겠다. :) – user3808088

+0

잘못되었습니다. 리스트 인수 ('argscmd')와'shell = True'를 함께 사용하지 마십시오. 문자열 인수는 목록 대신 대부분의 경우'shell = True'와 함께 사용해야합니다. OPs의 경우'shell = True'가 필요하다는 언급은 없습니다. – jfs

0

더 같은 execfork입니다 :

cmd = ['c2d', inname] 
cmd += '-clip 1% 99% -type short -stretch 1% 99% 0 255 -o'.split() 
cmd += [outname] 
p = subprocess.Popen(cmd) 
...