주문하다
$ find ~/foo/ -type f -iname "*.txt" -print0 | parallel -0 cat
사용GNU 병렬.txt
아래의 모든 파일을 인쇄하십시오 ~/foo/
.
이 bash 명령을 호출하려는 Python 스크립트가 있습니다.
import subprocess, sys
def runBashCommand(my_command):
process = subprocess.Popen(my_command.split(), stdout=subprocess.PIPE)
output = process.communicate()[0]
return None
def makeCommand(my_path):
return "find {} -type f -iname \"*.txt\" -print0 | parallel -0 cat".format(my_path)
발행 된
>>> makeCommand('~/foo/')
반품
'find ~/foo/ -type f -iname "*.txt" -print0 | parallel -0 cat'
그러나 발행
>>> runBashCommand(makeCommand('~/foo/'))
오류 발생
find: paths must precede expression: |
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
내 스크립트에 무슨 문제가 있나요?
답변1
bash
실제로 명령을 실행하지 않습니다 . 당신이 하고 있는 일은 실행 파일을 직접 실행하고 인수를 전달하는 것입니다.
다음 스크립트를 시도해보고 무슨 일이 일어나는지 확인하세요.
import subprocess
p = subprocess.Popen(["echo", "a", "b", "|", "rev"], stdout=subprocess.PIPE)
print p.communicate()
출력은 다음과 같습니다:
('a b | rev\n', None)
리디렉션이 발생하지 않으며 "|"가 그대로 전달됩니다. 즉, 마치 자신이 입력한 것과 같습니다 find ... \| parallel ...
. 따라서 오류가 발생했습니다.
문제를 해결하는 방법에는 두 가지가 있습니다.
가장 쉬운 방법은
shell=True
에 전달하는 것입니다subprocess.Popen
. 이렇게 하면 필요한 모든 항목을 포함하여 셸을 통해 실행됩니다. 이렇게 하려면 배열 대신 문자열도 전달해야 합니다.import subprocess p = subprocess.Popen("echo a b | rev", stdout=subprocess.PIPE, shell=True) print p.communicate() # Result: ('b a\n', None)
이렇게 하면,문자열의 매개변수 대체에는 매우 주의하세요..
강력한 접근 방식: Python을 사용하여 두 프로세스를 열고 함께 연결합니다.
import subprocess # First command p1 = subprocess.Popen(["echo", "a", "b"], stdout=subprocess.PIPE) # Second command's input linked to the first one's output p2 = subprocess.Popen(["rev"], stdin=p1.stdout, stdout=subprocess.PIPE) # Read from p2 to get the output print p2.communicate() # Result: ('b a\n', None)
이는 더 강력하고 추가 쉘을 생성하지 않지만 반면에 더 많은 타이핑을 필요로 합니다. 이렇게 하면,알아채다아니요쉘 교체 발생. 귀하의 경우에는 필요하지 않은 것 같지만 을 사용하려면
~
Python(예: )을 통해os.getenv("HOME")
가져와야 합니다.
답변2
명령 문자열에는 및 split()
등 셸에서 처리해야 하는 문자가 포함되어 있으므로 사용할 수 없습니다 . 사용 버전:~
|
process = subprocess.Popen(my_command, stdout=subprocess.PIPE, shell=True)