ฆ่ากระบวนการตามชื่อ?


100

ฉันพยายามฆ่ากระบวนการ (โดยเฉพาะ iChat) ในบรรทัดคำสั่งฉันใช้คำสั่งเหล่านี้:

ps -A | grep iChat 

จากนั้น:

kill -9 PID

อย่างไรก็ตามฉันไม่แน่ใจว่าจะแปลคำสั่งเหล่านี้เป็น Python อย่างไร

คำตอบ:


85

สมมติว่าคุณอยู่บนแพลตฟอร์มที่เหมือน Unix ( ps -Aมีอยู่แล้ว)

>>> import subprocess, signal
>>> import os
>>> p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
>>> out, err = p.communicate()

ให้ps -Aผลลัพธ์ของคุณในoutตัวแปร (สตริง) คุณสามารถแบ่งมันออกเป็นเส้นและวนซ้ำได้ ... :

>>> for line in out.splitlines():
...   if 'iChat' in line:
...     pid = int(line.split(None, 1)[0])
...     os.kill(pid, signal.SIGKILL)
... 

(คุณสามารถหลีกเลี่ยงการนำเข้าsignalและใช้9แทนได้signal.SIGKILLแต่ฉันไม่ชอบสไตล์นั้นเป็นพิเศษดังนั้นฉันจึงควรใช้ค่าคงที่ที่ตั้งชื่อด้วยวิธีนี้)

แน่นอนว่าคุณสามารถประมวลผลที่ซับซ้อนกว่านี้ได้มากในบรรทัดเหล่านี้ แต่มันจะเลียนแบบสิ่งที่คุณกำลังทำอยู่ในเชลล์

หากสิ่งที่คุณต้องการหลีกเลี่ยงpsนั่นเป็นเรื่องยากที่จะทำในระบบที่คล้าย Unix อื่น ๆ ( psเป็น API ทั่วไปในการรับรายการกระบวนการหรือไม่) แต่ถ้าคุณมีระบบที่คล้าย Unix เฉพาะในใจเท่านั้น (ไม่ต้องการการพกพาข้ามแพลตฟอร์มใด ๆ ) อาจเป็นไปได้ โดยเฉพาะบน Linux /procระบบไฟล์หลอกจะมีประโยชน์มาก แต่คุณจะต้องชี้แจงข้อกำหนดที่แน่นอนของคุณก่อนที่เราจะสามารถช่วยได้ในส่วนหลังนี้


1
ได้ผลดีมาก! ฉันใช้งานระบบ Mac ดังนั้นฉันคิดว่านี่จะสมบูรณ์แบบ ขอบคุณสำหรับความช่วยเหลือ.
— แอรอน

ด้านบนใช้งานได้กับ. nix แต่ไม่ใช่ pythonic วิธีการอนุมัติดังที่โพสต์ด้านล่างคือการใช้วิธี os.system ('taskkill / f / im exampleProcess.exe') ซึ่งเป็นส่วนหนึ่งของ core python
— Jonesome Reinstate Monica

@ Jonesome: คำตอบของคุณดูเหมือนจะเป็นสำหรับ Windows (เนื่องจากไวยากรณ์คำสั่งและชื่อไฟล์. exe) แต่คำถามน่าจะเป็นสำหรับ Mac OS
— Vasudev Ram

ฉันชอบคำตอบนี้สำหรับ Giampaolo Rodolàเพราะแม้ว่าจะไม่ใช่ Pythonic มาก แต่ก็ทำงานบน Windows โดยสมมติว่าคุณติดตั้ง Cygwin หรือ Msys ไว้ psutil ไม่มีอยู่ใน Python 2.7.10 บน Windows การพยายาม "pip install psutil" ล้มเหลวในเครื่องของฉันโดยบอกว่าฉันจำเป็นต้องติดตั้ง Visual C ++ 9.0 กรูว่า! ฉันอยากจะติดตั้ง Cygwin หรือ Msys มากกว่า
— Andrew Bainbridge

ทำงานใน Windows ตั้งแต่ Python 3.2 แต่โดยปกติสัญญาณจะเป็นรหัสออกของกระบวนการที่ถูกฆ่า
— Cees Timmerman

208

psutilสามารถค้นหากระบวนการตามชื่อและฆ่ามัน:

import psutil

PROCNAME = "python.exe"

for proc in psutil.process_iter():
    # check whether the process name matches
    if proc.name() == PROCNAME:
        proc.kill()

52
นี้. เพราะมันเป็นข้ามแพลตฟอร์ม
— Bengt

2
หรือถ้าคุณต้องการโดยใช้บรรทัดคำสั่งเช่น if "your_python_script.py" ใน proc.cmdline: ..kill
— OWADVL

11
ข้อเสียคือต้องใช้psutilแพคเกจซึ่งอาจไม่มีอยู่ในเครื่องเป้าหมาย
— CadentOrange

1
@ เบ็งต. นี่ไม่ใช่การข้ามแพลตฟอร์มหากคุณรวม Windows! psutil ไม่ได้เป็นส่วนหนึ่งของ Python 2.7.10 และ "pip install psutil" ล้มเหลวเว้นแต่คุณจะติดตั้ง Visual C ++ 9.0 ซึ่งจะใช้ไม่ได้ในหลาย ๆ กรณี ยังไงก็ขอแสดงความยินดีกับ 17 upvotes ของคุณ :-)
— Andrew Bainbridge

5
"pip install psutil" จะทำงานได้ดีเพราะจะดึงรุ่นล้อบน pypi และไม่คุณไม่จำเป็นต้องมีคอมไพเลอร์
— Giampaolo Rodolà

35

หากคุณต้องพิจารณากรณีของ Windows เพื่อที่จะข้ามแพลตฟอร์มให้ลองทำดังต่อไปนี้:

os.system('taskkill /f /im exampleProcess.exe')

@ alansiqueira27 น่าเสียดายที่เป็นเคส Windows cmd เท่านั้น คุณต้องดูคำตอบด้านบนสำหรับโซลูชันข้ามแพลตฟอร์ม
— limitcracker

สิ่งนี้ใช้ได้กับกรณีการใช้งานของฉัน Thanx! โปรดทราบว่าสิ่งนี้เป็นไปอย่างเรียบร้อยมันจะฆ่ากระบวนการทั้งหมดด้วยชื่อนั้นดังนั้นหากคุณมี Y.exe หลายตัวที่ไม่ได้ยุติ ID กระบวนการทั้งหมดของมันจะถูกยกเลิก
— CommutativeAlgebraStudent

22

หากคุณมี killall:

os.system("killall -9 iChat");

หรือ:

os.system("ps -C iChat -o pid=|xargs kill -9")

9
นอกจากนี้ยังมีpkillแม้ว่าฉันคิดว่าฉันเป็นคนเดียวในโลกที่ใช้มันแทนkillall
— Michael Mrozek

1
โอเคใช่ดูเหมือนว่าคำสั่งแรกจะทำงานได้สมบูรณ์แบบ ขอบคุณสำหรับความช่วยเหลือ
— แอรอน

1
@MichaelMrozek คุณจะอยู่กับความรู้สึกหวาน ๆ ของการพิมพ์สิ่งต่างๆได้killall javaอย่างไร?
— Alois Mahdal

@ ไมเคิลฉันใช้pkillเพราะสิ่งเดียวที่killallฉันรู้คือ "ฆ่าทุกอย่าง"
— Kyle Strand


4

คุณสามารถลองสิ่งนี้ แต่ก่อนที่คุณจะต้องติดตั้งpsutilโดยใช้ไฟล์sudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()

อย่างน้อยก็พกพาได้แม้ว่าคำตอบที่ยอมรับจะอธิบายวิธีแก้ปัญหานี้แล้วก็ตาม
— Jean-François Fabre

1

รหัสด้านล่างจะฆ่าโปรแกรมที่มุ่งเน้น iChat ทั้งหมด:

p = subprocess.Popen(['pgrep', '-l' , 'iChat'], stdout=subprocess.PIPE)
out, err = p.communicate()

for line in out.splitlines():        
    line = bytes.decode(line)
    pid = int(line.split(None, 1)[0])
    os.kill(pid, signal.SIGKILL)

1

รับวัตถุกระบวนการโดยใช้Process.

>>> import psutil
>>> p = psutil.Process(23442)
>>> p
psutil.Process(pid=23442, name='python3.6', started='09:24:16')
>>> p.kill()
>>> 

0

คุณสามารถใช้pkill <process_name>ในระบบยูนิกซ์เพื่อฆ่ากระบวนการตามชื่อ

จากนั้นรหัส python จะเป็น:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)

ระบบทั้งหมดที่ฉันใช้คือ Mac และเมื่อฉันพยายามเรียกใช้ pkill มันก็บอกฉันว่าไม่พบคำสั่ง
— แอรอน

0

คุณสามารถใช้โมดูล WMI เพื่อทำสิ่งนี้บน windows ได้แม้ว่ามันจะเยอะกว่าที่คุณเคยใช้ import WMIใช้เวลานานและมีความเจ็บปวดระดับกลางในการดำเนินการ


0

หากคุณต้องการฆ่ากระบวนการหรือ cmd.exe ที่มีชื่อเฉพาะ

import csv, os
import subprocess
# ## Find the command prompt windows.
# ## Collect the details of the command prompt windows and assign them.
tasks = csv.DictReader(subprocess.check_output('tasklist /fi "imagename eq cmd.exe" /v /fo csv').splitlines(), delimiter=',', quotechar='"')
# ## The cmds with titles to be closed.
titles= ["Ploter", "scanFolder"]

# ## Find the PIDs of the cmds with the above titles.
PIDList = []
for line in tasks:
    for title in titles:
        if  title in line['Window Title']:
           print line['Window Title']       
           PIDList.append(line['PID'])

# ## Kill the CMDs carrying the PIDs in PIDList
for id in PIDList:
    os.system('taskkill /pid ' + id ) 

หวังว่าจะช่วยได้ พวกเขาอาจมีทางออกที่ดีกว่ามากมายสำหรับฉัน


0

คำตอบของ Alex Martelli ใช้ไม่ได้ใน Python 3 เนื่องจากoutจะเป็นวัตถุไบต์และส่งผลให้TypeError: a bytes-like object is required, not 'str'เมื่อทำการทดสอบif 'iChat' in line:การทดสอบเมื่อ

อ้างจากเอกสารกระบวนการย่อย:

สื่อสาร () ส่งคืนทูเพิล (stdout_data, stderr_data) ข้อมูลจะเป็นสตริงหากสตรีมถูกเปิดในโหมดข้อความ มิฉะนั้นไบต์

สำหรับ Python 3 สิ่งนี้แก้ไขได้โดยการเพิ่มtext=True(> = Python 3.7) หรือuniversal_newlines=Trueอาร์กิวเมนต์ให้กับตัวPopenสร้าง outจากนั้นจะถูกส่งกลับเป็นวัตถุสตริง

import subprocess, signal
import os

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE, text=True)
out, err = p.communicate()

for line in out.splitlines():
    if 'iChat' in line:
        pid = int(line.split(None, 1)[0])    
        os.kill(pid, signal.SIGKILL)

หรือคุณสามารถสร้างสตริงโดยใช้เมธอด decode () ของไบต์

import subprocess, signal
import os

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
out, err = p.communicate()

for line in out.splitlines():
    if 'iChat' in line.decode('utf-8'):
        pid = int(line.split(None, 1)[0])    
        os.kill(pid, signal.SIGKILL)


-1
import os, signal

def check_kill_process(pstring):
    for line in os.popen("ps ax | grep " + pstring + " | grep -v grep"):
        fields = line.split()
        pid = fields[0]
        os.kill(int(pid), signal.SIGKILL)

-2
import psutil
pid_list=psutil.get_pid_list()
print pid_list
p = psutil.Process(1052)
print p.name
for i in pid_list:
    p = psutil.Process(i)
    p_name=p.name
    print str(i)+" "+str(p.name)
    if p_name=="PerfExp.exe":
        print "*"*20+" mam ho "+"*"*20
        p.kill()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.