2013-07-25 16 views
22

Tôi đang cố gắng viết một số tập lệnh ngắn trong python sẽ bắt đầu một mã python khác trong tiến trình con nếu chưa được bắt đầu khác chấm dứt thiết bị đầu cuối & ứng dụng (Linux).Làm thế nào để chấm dứt quá trình từ Python bằng cách sử dụng pid?

Vì vậy, nó trông giống như:

#!/usr/bin/python 
from subprocess import Popen 

text_file = open(".proc", "rb") 
dat = text_file.read() 
text_file.close() 

def do(dat): 

    text_file = open(".proc", "w") 
    p = None 

    if dat == "x" : 

     p = Popen('python StripCore.py', shell=True) 
     text_file.write(str(p.pid)) 

    else : 
     text_file.write("x") 

     p = # Assign process by pid/pid from int(dat) 
     p.terminate() 

    text_file.close() 

do(dat) 

Có vấn đề thiếu kiến ​​thức để Proces tên gọi theo pid mà ứng dụng đọc từ tập tin ".proc". Vấn đề khác là thông dịch viên nói rằng chuỗi có tên dat không bằng "x" ??? Những gì tôi đã bỏ lỡ?

+2

Tại sao bạn truyền 'shell = True'? AFAIK nó không cần thiết trong trường hợp sử dụng của bạn. Cũng lưu ý rằng khi sử dụng 'shell = True', pid được trả về bởi' p.pid' là * không * pid của quá trình python, nhưng pid của shell sinh ra để thực thi quá trình này. – Bakuriu

+0

+1 cho nhận xét của bạn, nhưng tôi coi nó là phù hợp vì tôi cũng cần đóng thiết bị đầu cuối. – Alex

Trả lời

52

Sử dụng psutil thư viện tuyệt vời nó khá đơn giản:

p = psutil.Process(pid) 
p.terminate() #or p.kill() 

Nếu bạn không muốn cài đặt một thư viện mới, bạn có thể sử dụng os mô-đun:

import os 
import signal 

os.kill(pid, signal.SIGTERM) #or signal.SIGKILL 

Nếu bạn quan tâm đến việc bắt đầu lệnh python StripCore.py nếu nó không chạy, và giết nó nếu không, bạn có thể sử dụng psutil để làm điều này đáng tin cậy ly.

Cái gì như:

import psutil 
from subprocess import Popen 

for process in psutil.process_iter(): 
    if process.cmdline() == ['python', 'StripCore.py']: 
     print('Process found. Terminating it.') 
     process.terminate() 
     break 
else: 
    print('Process not found: starting it.') 
    Popen(['python', 'StripCore.py']) 

mẫu chạy:

$python test_strip.py #test_strip.py contains the code above 
Process not found: starting it. 
$python test_strip.py 
Process found. Terminating it. 
$python test_strip.py 
Process not found: starting it. 
$killall python 
$python test_strip.py 
Process not found: starting it. 
$python test_strip.py 
Process found. Terminating it. 
$python test_strip.py 
Process not found: starting it. 

Note: Trong trước psutil phiên bản cmdline là một thuộc tính thay vì một phương pháp.

+0

Cảm ơn, nhưng vấn đề chính đối với tôi là làm thế nào để có được pid của ứng dụng đang chạy? – Alex

+3

@Alex Ý của bạn là gì? Bạn muốn chấm dứt quá trình đang thực hiện? Sau đó, chỉ cần sử dụng 'sys.exit()'. Nếu bạn muốn truy cập vào 'pid' của tiến trình hiện tại, sử dụng' os.getpid() '. – Bakuriu

+0

at_Bakuriu xin lỗi (mi dispiace). Tôi chỉ muốn thực hiện kịch bản mà sẽ chạy một số ứng dụng nếu nó không được bắt đầu. Và nếu ứng dụng được bắt đầu, để chấm dứt ứng dụng này và bản thân cũng vậy. – Alex

2

Tôi muốn làm điều tương tự, nhưng tôi muốn làm điều đó trong một tệp.

Vì vậy, logic sẽ là:

  • nếu một kịch bản với tên của tôi đang chạy, giết nó, sau đó thoát
  • nếu một kịch bản với tên của tôi không chạy, làm công cụ

Tôi đã sửa đổi câu trả lời của Bakuriu và đã đưa ra điều này:

from os import getpid 
from sys import argv, exit 
import psutil ## pip install psutil 

myname = argv[0] 
mypid = getpid() 
for process in psutil.process_iter(): 
    if process.pid != mypid: 
     for path in process.cmdline(): 
      if myname in path: 
       print "process found" 
       process.terminate() 
       exit() 

## your program starts here... 

Chạy tập lệnh sẽ làm bất cứ điều gì kịch bản. Chạy một thể hiện khác của tập lệnh sẽ giết bất kỳ phiên bản hiện tại nào của tập lệnh.

Tôi sử dụng tùy chọn này để hiển thị tiện ích con lịch PyGTK nhỏ chạy khi tôi nhấp vào đồng hồ. Nếu tôi nhấp và lịch không hiển thị, lịch hiển thị. Nếu lịch đang chạy và tôi nhấp vào đồng hồ, lịch sẽ biến mất.