2015-05-22 28 views
1

環境:樹莓派喘息POPEN沒有響應殺

我有一個使用POPEN調用另一個Python程序

from subprocess import * 

oJob = Popen('sudo python mypgm.py',shell=True) 

另一個菜單選項應該立即停止作業

Python程序
oJob.kill() 

但工作仍在進行中?

+0

除了別人提出的'shell = True'是邪惡的,你不能殺死你不擁有的工作,而'sudo'讓工作由root擁有,而不是你自己。 –

+0

如果在我的python pgm上執行chgmod + x我得到關於wiringPi的錯誤消息,需要使用sudo來使用wiringPiSetup – Rod

+0

你需要'sudo'並不會阻止它使你無法表示進程如此高 - 因此,我真的不知道你的評論是否打算完成。現在,你可以'sudo kill $ {pid}'獲得'oJob'的進程ID,這樣你的kill也可以升級權限,或者你可以在'sudo'下運行整個程序,因此已經擁有升級權限無論是發射還是殺死,從而避免再次需要使用'sudo'。 –

回答

1

您需要添加一個創建標誌ARG

oJob = Popen('sudo python mypgm.py',shell=True, creationflags = subprocess.CREATE_NEW_PROCESS_GROUP) 

source

subprocess.CREATE_NEW_PROCESS_GROUP 一個POPEN creationflags參數指定一個新的進程組將被創建。此標誌對於在子流程中使用os.kill()是必需的。

編輯我同意關於如何導入的東西的評論,爲什麼你得到的東西是不確定的。另外,其他的答案似乎是在正確的軌道上得到PID

import subprocess as sub 

oJob = sub.Popen('sudo python mypgm.py', creationflags = sub.CREATE_NEW_PROCESS_GROUP) 
oJob.kill() 

警告執行,從不受信任的來源包括unsanitized輸入shell命令使得程序容易受到外殼注塑,一個嚴重的安全漏洞,可導致在任意命令執行中。出於這個原因,使用shell=True強烈建議不要在命令字符串是從外部輸入構成情況:

+0

我正在使用「from subprocess import *」,它表示子流程未定義 – Rod

+0

然後,您已經將CREATE_NEW_PROCESS_GROUP導入到全局名稱空間中。但是,無論如何,您不應該使用'from subprocess import *'。使用'import subprocess'或者只指定你想要導入的名字。例如,'從子流程導入Popen,CREATE_NEW_PROCESS_GROUP'。 – chepner

+0

這個工作在樹莓派Python版本 – Rod

1

當你添加選項shell=True,蟒蛇啓動一個殼,進而殼啓動過程python mymgm.py。你正在殺死這個沒有殺死運行mymgm.py的子進程的shell進程。

爲了確保該子進程在oJob.kill上被殺死,您需要將它們全部歸入一個進程組,並使shell進程成爲組長。 的代碼,

import os 
import signal 
import subprocess 

# The os.setsid() is passed in the argument preexec_fn so 
# it's run after the fork() and before exec() to run the shell. 
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, 
         shell=True, preexec_fn=os.setsid) 

os.killpg(pro.pid, signal.SIGTERM) # Send the signal to all the process groups 

當您發送SIGTERM信號shell進程,它會殺死所有的子進程也是如此。

+0

也許是真的,也許不是。一些shell自動執行它們被調用的字符串中的最後一個命令。 –