2010-08-12 3 views
3

저는 파이썬에서 사용자가 인터넷 라디오 채널을 재생할 수있는 작은 gui-frontend를 작성했습니다. 프로그램 파이톤 구성 프로세스는()로 채널을 선국에 mplayer를 initizalize 위해 사용하는 예 : 다음 p.pid를 저장하고, 사용자가 다음 코드를 수신 중지하기를 원할 때 사용된다 Python : subprocess()가 Ubuntu에서 2 프로세스를 시작하고 OpenSUSE에서 1 프로세스를 시작하는 이유는 무엇입니까?

runn = "mplayer http://77.111.88.131:8010" 
p = subprocess.Popen(runn, shell=True) 
pid = int(p.pid) 
wait = os.waitpid(p.pid, 1)

:

os.kill(p.pid, 9)

이것은 OpenSUSE에서 완벽하게 작동하지만 Ubuntu에서는 작동하지 않습니다. 우분투는 실제로 두 개의 별도 프로세스를 시작하는 것 같습니다. 터미널 출력 :

오픈 수세 11.3 :

$ pgrep mplayer 
22845 

우분투 10.04 : 다른 프로그램을 실행할 때이 또한 적용

$ pgrep mplayer 
22846 
22847 

. 아무도 이유를 아나요? 나는이 응용 프로그램이 모든 배포판에서 실행되기를 정말로 원합니다. 그래서 어떤 도움도 깊은 평가를 받았습니다.

+0

'ps -ef | fgrep mplayer'? – Omnifarious

답변

4

이 시도 : 무슨 일이 일어나고 있는지에 관해서는

p = subprocess.Popen(runn.split(), shell=False) 

내 생각이 많이 ...

당신은 shell=True 하위 프로세스가 실제로이 명령 sh -c "your string"을 시작했다고 가정합니다. 그런 다음 sh 명령은 문자열을 해석하고 쉘 프롬프트에서 입력 한 것처럼 명령을 실행합니다 (다소간). 일반적으로 이것은 두 개의 프로세스가됩니다. 하나는 sh -c "your string"이고 다른 하나는 자식이됩니다 ( your string).

일부 버전의 sh에는 특정 조건에서 명령이 자동으로 exec 인 최적화 기능이 있습니다. 그들은 마지막 명령 인 sh이 실행되고 sh은 계속 붙잡아 두지 않습니다. sh -c을 사용하여 명령을 실행하면 거의 항상 sh의 호출이 실행중인 명령으로 바뀌어 하나의 프로세스가됩니다.

내 의견으로는 subprocess.Popenshell=True으로 호출하는 것은 정말 나쁜 생각입니다. 쉘 메타 문자가 sh -c으로 해석되기 때문에이를 수행하여 보안 문제를 해결할 수 있습니다.

+0

철저한 설명에 감사드립니다. 이것은 내 문제를 해결했다. 좋은 하루 되세요 :) – frigg

1

나는 정확한 답을 가지고 있지만, 여기에 조사하는 방법은 여러 가지입니다하지 않습니다

사용 pstree 프로세스 사이의 부모/자식 관계를 조사 할 수 있습니다.

ps -awux을 사용하면 모든 프로세스의 전체 명령 줄 인수를 볼 수 있습니다.

shell=True을 사용하면 mplayer을 시작하는 셸 프로세스 (예 : /bin/bash)가 시작됩니다. 그것은 조사를위한 또 다른 수단 일 것입니다. 두 시스템이 같은 쉘을 사용하고 있습니까?

두 시스템 모두 동일한 버전의 mplayer를 사용합니까? 파이썬?

0

subprocess.Popenseveral useful methods 인 Popen 개체를 반환합니다. os.kill을 직접 사용하여 작업을 종료하는 것은 좋지 않은 생각 일 수 있습니다.

Popen 오브젝트의 p.terminate() 또는 p.kill() 메소드를 사용하면 동일한 문제가 발생합니까?

+0

그냥 p.terminate()가 파이썬 2.6 이전에 존재하지 않았다는 것을 깨달았습니다. OP가'os.kill (p.pid)'를 사용하는 이유입니다. docs 나는 다른 사람들을 향해 있습니다! –

관련 문제