2014-07-16 4 views
2

을 읽는 : 나는 (파이썬의 외부) 콘솔에서 명령을 실행하면나는 다음과 같은 한 파이썬에서 쉘 명령을 실행하고 출력

cmd = "ps aux | grep 'java -jar' | grep -v grep | awk '//{print $2}'".split(' ') 
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = p.communicate() 
print out 

, 내가 원하는 출력을 얻을. 파이썬에서 위의 코드를 실행하면 빈 행이 인쇄됩니다. cmd (특히 | 연산자)이있는 것으로 가정하고 있지만 확신 할 수 없습니다.

나는 파이프로 연결된과 같이로, 원래 명령의 각 부분에 대한 Popen()에 단일 통화를 사용하는 데 필요한 표준 파이썬

+1

[파이썬 하위 프로세스 명령과 파이프] (https://stackoverflow.com/questions/13332268/python-subprocess-command-with-pipe)의 중복 가능 – RomanHotsiy

+0

운영 체제에서 pgrep 명령을 제공하는 경우 이런 식으로 ps의 출력을 필터링하는 것보다 더 나은 방법입니다. –

+1

가능한 [Python에서 셸 명령을 실행하고 출력을 캡처] 중복 (0120-17503)을 참조하십시오. –

답변

3

을 2.6.6 설치 (추가 모듈)이 달성하지 필요 in

import subprocess 

p1 = subprocess.Popen(["ps", "aux"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
p2 = subprocess.Popen(["grep", "java -jar"], stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
p3 = subprocess.Popen(["grep", "-v", "grep"], stdin=p2.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
p4 = subprocess.Popen(["awk", "//{print $2}"], stdin=p3.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = p4.communicate() 

print out 

subprocess documentation에 대한 심층적 인 토론이 있습니다.

1

쉘 파이프 라인에는 Python 코드로 쉽게 대체 할 수없는 명령이 하나만 있습니다. 그래서 당신은 몇 가지 외부 프로세스를 시작하고 자신의 입력과 출력을 연결하지만, 난 그냥 ps aux를 시작하고 필터링하고 원하는 데이터를 추출하는 몇 가지 파이썬 코드를 추가 할 수 있습니다 만 실행을 실행 기본적으로

from subprocess import PIPE, Popen 


def main(): 
    process = Popen(['ps', 'aux'], stdout=PIPE) 
    pids = [ 
     line.split(None, 2)[1] for line in process.stdout if 'java -jar' in line 
    ] 
    process.wait() 
    print '\n'.join(pids) 


if __name__ == '__main__': 
    main() 
2

Popen을, 쉘 명령 줄이 아님. 당신이 Popen에 인수 목록을 통과하면 그들은 그것의 인수 하나 실행 파일을 호출해야합니다 :

import subprocess 

proc = subprocess.Popen(['ps', 'aux']) 

을 또한, 당신은 하지 사용 str.split 명령을 분할해야 있습니다 이유는

>>> "ps aux | grep 'java -jar'  | grep -v grep | awk '//{print $2}'".split(' ') 
['ps', 'aux', '|', 'grep', "'java", "-jar'", '', '', '', '', '|', 'grep', '-v', 'grep', '|', 'awk', "'//{print", "$2}'"] 

메모 방법 :

  • 인용 된 인수 (예 : 'java -jar')이 분할됩니다.
  • 연속 된 공백이 여러 개 있으면 빈 인수가 발생합니다.

파이썬 이미 합리적인 방식으로 명령 줄을 분리하는 방법을 알고있는 모듈을 제공, 그것은 shlex입니다 :

>>> shlex.split("ps aux | grep 'java -jar'  | grep -v grep | awk '//{print $2}'") 
['ps', 'aux', '|', 'grep', 'java -jar', '|', 'grep', '-v', 'grep', '|', 'awk', '//{print $2}'] 

참고 인용 방법 인수를 보존하고, 여러 공간은 정상적으로 처리됩니다. Popen하지는 기본적으로 파이프로 |을 해석하기 때문에 아직 당신은 , Popen에 결과를 전달하지 수 있습니다.

쉘 명령 줄을 실행하려면 (예 : 파이프, 경로 확장, 리디렉션 등과 같은 쉘 기능을 사용하는 경우) shell=True을 전달해야합니다.이 경우 하지Popen에 argumento로 문자열 목록을 통과하지만 전체 명령 줄입니다 문자열한다 : 당신이 shell=True와 문자열 목록을 전달하면

proc = subprocess.Popen("ps aux | grep 'java -jar' | grep -v grep | awk '//{print $2}'", shell=True) 

는 의미는이 다른 요소 : 첫 번째 요소는 명령 줄이어야하며 다른 요소는 사용 된 셸의 옵션으로 전달되어야합니다. 내 컴퓨터에 예를 들어, 기본 쉘 (sh)가 실행됩니다 stderr 모든 프로세스에 표시 것 -x 옵션이 있습니다 다음은 /bin/sh 명령을 실행이 시작된 것을 볼 수 있습니다

>>> from subprocess import Popen 
>>> proc = Popen(['ps aux | grep python3', '-x'], shell=True) 
>>> 
username 7301 0.1 0.1 39440 7408 pts/9 S+ 12:57 0:00 python3 
username 7302 0.0 0.0 4444 640 pts/9 S+ 12:58 0:00 /bin/sh -c ps aux | grep python3 -x 
username 7304 0.0 0.0 15968 904 pts/9 S+ 12:58 0:00 grep python3 

ps aux | python3와와 -x 옵션

(모두 Popen의 설명서에 설명되어 있습니다.)


당신이 원하는 것을 달성하기 위해이 말했다, 한 가지 방법은 subprocess.check_output 사용하는 것입니다 : 그러나 이것은 파이썬에서 사용할 수 없습니다

subprocess.check_output("ps aux | grep 'java -jar' | grep -v grep | awk '//{print $2}'", shell=True) 

을 < 2.7 그래서 당신은 Popencommunicate()을 사용할 수 있습니다

대안은 shell=True (일반적으로 v 여러 프로세스를 사용하여 파이프를 쓰기 수동 shell=True 일부 보안 위험을 소개하기 때문에, 좋은 일을 ERY)과 : 당신은 표준 오류에 대해 걱정하지 않는 경우에 당신이 그것을 지정 피할 수

from subprocess import Popen, PIPE 

ps = Popen(['ps', 'aux'], stdout=PIPE) 
grep_java = Popen(['grep', 'java -jar'], stdin=ps.stdout, stdout=PIPE) 
grep_grep = Popen(['grep', '-v', 'grep'], stdin=grep_java.stdout, stdout=PIPE) 
awk = Popen(['awk', '//{print $2}'], stdin=grep_grep.stdout, stdout=PIPE) 
out, err = awk.communicate() 

grep_grep.wait() 
grep_java.wait() 
ps.wait() 

참고. 그런 다음 현재 프로세스 중 하나를 상속받습니다.

+0

전체 설명 주셔서 감사합니다 ...이 upvote을 부여했습니다. – Cheetah

관련 문제