2012-01-23 5 views
4

내가는 popen 실행 싶습니다파이썬는 popen 그렙은

쉘에서 실행
grep -i --line-buffered "grave" data/*.txt 

이 나에게 원하는 결과를 제공합니다.

['grep', '-i', '--line-buffered', 'grave', 'data/*.txt'] 

p = subprocess.Popen(args)의 결과는

입니다 : 내가 시작하면, 내가 grep, 파이썬 REPL을 테스트하고 the instruction from the docs에 따라 바로 그 디렉토리에, 나는으로는 popen을 공급하는 적절한 인수 목록해야한다 무엇을 얻기
grep: data/*.txt: No such file or directory 

내가 p = subprocess.Popen(args, shell=True)를하려고하면, 내가 얻을 : 원하는 프로세스를 수행하는 방법에 대한

Usage: grep [OPTION]... PATTERN [FILE]... 
Try `grep --help' for more information. 

어떤 도움을? 나는 MacOS Lion에 있습니다.

답변

7

*을 bash에 입력하면 명령을 실행하기 전에 쉘이 지정된 디렉토리의 파일로 확장합니다. 파이썬의 Popen은 그런 일을하지 않으므로 Popen을 호출 할 때 grep에게 디렉토리에있는 .txt 파일 대신 data 디렉토리에 *.txt이라는 파일이 있다는 것을 말하는 것과 같은 일을합니다. 해당 파일이 존재하지 않고 예상 한 오류가 발생합니다.

이는 popen에 shell=True를 전달하여 당신이 쉘을 통해 명령을 실행하기 위해 파이썬을 말할 수있는이 문제를 해결하려면 다음에 번역됩니다

subprocess.Popen('grep -i --line-buffered grave data/*.txt', shell=True) 

:

subprocess.Popen(['/bin/sh', '-c', 'grep -i --line-buffered "grave" data/*.txt']) 

바와 같이 the documentation of Popen에서 설명했다.

/bin/sh -c "grep -i --line-buffered "grave" data/*.txt" (N.B. 명령을 따옴표로 묶어 sh의 단일 인수로 지정)을 실행하려면 여기에서 목록 대신 문자열을 사용해야합니다. 목록을 사용하면이 명령이 실행됩니다 : /bin/sh -c grep -i --line-buffered "grave" data/*.txt, 이는 단순히 grep을 실행하는 결과를 제공합니다. . 데이터/* TXT 당신은 glob 모듈을 사용하여, 예를 들어, youself 그것을 수행해야합니다

:

4

문제는 쉘 파일 당신을 위해 글 로빙을 만드는 것입니다.

import glob 
cmd_line = ['grep', '-i', '--line-buffered', 'grave'] + glob.glob('data/*.txt') 
+0

+1 플랫폼 독립성 –

+0

감사합니다. 플랫폼 독립성을 높이려면 'data/\ *. txt'대신 os.path.join ('data', '\ *. txt')을 사용해야합니다. –