ฉันจะฆ่ากระบวนการด้วยชื่อแทนที่จะเป็น PID ได้อย่างไร


349

บางครั้งเมื่อฉันพยายามเริ่ม Firefox คำว่า "กระบวนการ Firefox กำลังทำงานอยู่" ดังนั้นฉันต้องทำสิ่งนี้:

jeremy@jeremy-desktop:~$ ps aux | grep firefox
jeremy    7451 25.0 27.4 170536 65680 ?        Sl   22:39   1:18 /usr/lib/firefox-3.0.1/firefox
jeremy    7578  0.0  0.3   3004   768 pts/0    S+   22:44   0:00 grep firefox
jeremy@jeremy-desktop:~$ kill 7451

สิ่งที่ฉันต้องการคือคำสั่งที่จะทำทุกอย่างให้ฉัน มันจะใช้สตริงอินพุตและgrepมัน (หรืออะไรก็ตาม) ในรายการของกระบวนการและจะฆ่ากระบวนการทั้งหมดในผลลัพธ์:

jeremy@jeremy-desktop:~$ killbyname firefox

ฉันพยายามทำมันใน PHP แต่exec('ps aux')ดูเหมือนว่าจะแสดงเฉพาะกระบวนการที่ถูกดำเนินการด้วยexec()สคริปต์ PHP เอง (ดังนั้นกระบวนการเดียวที่แสดงก็คือตัวมันเอง)


เมื่อฉันได้หน้าต่างที่แจ้งว่า Firefox ทำงานแล้วฉันมักจะต้องรอหนึ่งวินาทีและฉันสามารถเรียกใช้ Firefox อีกครั้ง (แน่นอนว่ามันอาจจะไม่ใช่ทุกกรณี)
nuoritoveri

1
นี่เป็นวิธีที่ปลอดภัยที่สุดอย่างที่ JohnB กล่าวไว้ในคำตอบนี้: stackoverflow.com/questions/6381229/…
tecnoshopbq


นี่เป็นคำถามเก่า แต่คุณช่วยเปลี่ยนคำตอบที่ยอมรับได้ไหม? สิ่งที่คุณทำเครื่องหมายว่าล้มเหลวด้วยหลายกระบวนการเช่นเดียวกับที่ดำเนินการโดย JVM
Luís de Sousa

สำหรับใครก็ตามที่อ้างถึงหัวข้อนี้ในความคิดเห็นข้างต้น Luis กำลังอ้างอิงคำตอบด้านล่างที่ทำเป็นpkill -f "Process name"คำสั่ง ...
Digger

คำตอบ:


505
pkill firefox

ข้อมูลเพิ่มเติม: http://linux.about.com/library/cmd/blcmdl1_pkill.htm


7
การใช้ pgrep เพื่อหาสิ่งที่คุณฆ่าก่อนที่คุณจะผ่านกระบวนการสังหารนั้นเป็นสิ่งที่ดี -fโดยเฉพาะอย่างยิ่งเมื่อใช้
Akrikos

pkill ไม่เป็นมิตรมาก คุณไม่สามารถตั้งชื่อแบบเดียวกับที่ killall รับได้
Octopus

2
pkill -U <username>ค่อนข้างมีประโยชน์ ฉันมีเว็บเซิร์ฟเวอร์Solarisซึ่งเป็นเว็บเซิร์ฟเวอร์ภูตตัวจริงมีการตั้งค่าเป็นบริการที่มีผู้ใช้เป็นของตัวเอง ดังนั้นการระบุโดยผู้ใช้จึงเป็นวิธีที่ง่าย / สะดวกในการเริ่มการรีสตาร์ท
Raystorm

6
เพื่อบังคับให้ฆ่า: pkill -9 firefox
Justas

วิธีนี้ใช้ได้ผลดีที่สุดครึ่งหนึ่ง คุณต้องการ-fแฟลกสำหรับโซลูชันรถโดยสารเป็นอย่างน้อย
Luís de Sousa

112

เป็นไปได้ที่จะใช้:

pkill -f "Process name"

สำหรับฉันมันทำงานได้อย่างสมบูรณ์แบบ มันเป็นสิ่งที่ฉันกำลังมองหา pkill ไม่ทำงานกับชื่อโดยไม่มีการตั้งค่าสถานะ

เมื่อ-fมีการตั้งค่าบรรทัดคำสั่งทั้งหมดจะใช้สำหรับการจับคู่รูปแบบ


2
พิเศษสำหรับการทำงานบางอย่างกับไวน์-fตัวเลือกที่มีความจำเป็นอย่างแท้จริง เช่นpkill -f "EvilWindowsServer.exe"
CodeBrauer

นี่ควรเป็นคำตอบที่ยอมรับได้ คำตอบแรกล้มเหลวด้วยโปรแกรมหลายชนิดเช่นที่ทำงานบน JVM
Luís de Sousa

1
ฉันต้องเพิ่มการ-fตั้งค่าสถานะเพื่อฆ่ากระบวนการพื้นหลังที่ใช้สคริปต์ Python
Mason

ในกรณีของฉันฉันต้องการ 2 ธง:pkill -f -9 PROCESSNAME
Slavik

64

คุณสามารถฆ่ากระบวนการตามชื่อด้วยkillall <name>

killallส่งสัญญาณไปยังกระบวนการทั้งหมดที่รันคำสั่งที่ระบุ หากไม่ได้ระบุชื่อสัญญาณ SIGTERM จะถูกส่ง

สัญญาณสามารถระบุได้อย่างใดอย่างหนึ่งตามชื่อ (เช่น-HUPหรือ-SIGHUP ) หรือตามจำนวน (เช่น -1 ) หรือตัวเลือก-s

หากชื่อคำสั่งไม่ใช่นิพจน์ปกติ (ตัวเลือก-r ) และมีเครื่องหมายทับ (/) กระบวนการที่เรียกใช้งานไฟล์นั้นจะถูกเลือกสำหรับการฆ่าโดยไม่ขึ้นกับชื่อของพวกเขา

แต่ถ้าคุณไม่เห็นกระบวนการด้วยps auxคุณอาจไม่มีสิทธิ์ฆ่ามัน ...


6
หากต้องการบังคับให้ยุติโปรแกรมที่ไม่ตอบสนองให้ส่ง KILL แทน TERM:killall -s KILL firefox
Martin Hansen


25

วิธีที่ง่ายที่สุดคือตรวจสอบก่อนว่าคุณได้รับรหัสกระบวนการที่ถูกต้องด้วย:

pgrep -f [part_of_a_command]

หากผลเป็นไปตามที่คาดไว้ ไปกับ:

pkill -f [part_of_a_command]

19

แปลก แต่ฉันไม่เห็นวิธีแก้ปัญหาเช่นนี้:

kill -9 `pidof firefox`

มันยังสามารถฆ่าหลายโพรเซส (หลาย pids) เช่น:

kill -9 `pgrep firefox`

ฉันชอบpidofเนื่องจากมีเอาต์พุตบรรทัดเดียว:

> pgrep firefox
6316
6565
> pidof firefox
6565 6316

kill: invalid number 'pidof myprogram'เมื่อฉันดำเนินการนี้ผมได้รับข้อผิดพลาด มีอะไรไม่ดีในที่นี่?
Brethlosze

นี่เพิ่งช่วยชีวิตฉันวันนี้ ... ฉันไม่ต้องการเขียนเพิ่ม แต่ฉันดีใจที่พบที่นี่ ขอบคุณชาย
MilMike

1
มาช้า แต่ในกรณีที่คนอื่นสงสัย ... @Brethlosze คุณใส่เห็บเดียวในขณะที่คำสั่งต้องมี backticks
spectras

ขอบคุณ .. ฉันจะเป็น (และฉันถูก) ตระหนักถึง backticks เหล่านี้ :)
Brethlosze

13

ฆ่ากระบวนการทั้งหมดที่มีsnippetในเส้นทางเริ่มต้น คุณสามารถฆ่าแอพทั้งหมดที่เริ่มต้นจากบางไดเรกทอรีโดยการวาง / directory / เป็นตัวอย่าง สิ่งนี้ค่อนข้างมีประโยชน์เมื่อคุณเริ่มส่วนประกอบหลายอย่างสำหรับแอปพลิเคชันเดียวกันจากไดเรกทอรีแอปเดียวกัน

ps ax | grep <snippet> | grep -v grep | awk '{print $1}' | xargs kill

* ฉันจะ preffer pgrep ถ้ามี


1
นี่คือการรวมกันของ antipatterns เห็นบ่อยครั้ง ใช้ regex ซึ่งไม่ตรงกับตัวเอง (หรือชื่อของสคริปต์ที่มี) และหลีกเลี่ยงการไร้ประโยชน์ grepps ax | awk '/[s]nippet/ { print $1 }' | xargs kill
tripleee

1
ในขณะที่หลีกเลี่ยง grep ที่ไร้ประโยชน์คุณไม่ได้หลีกเลี่ยงความผิดพลาดและความสามารถในการใช้คำสั่งในกระบวนการอัตโนมัติที่กำหนดพารามิเตอร์ <snippet>
Mike

นี่เป็นวิธีที่ดีที่สุดที่จะทำ!
Abhinandan Dubey

เป็นเรื่องที่ดีที่จะเข้าใจว่าทำไมงานของ @ tripleee [s]ในแง่ที่ไม่เข้ากับกระบวนการ awk เอง
andig

เพราะ regex [x]yตรงกับสตริงxyแต่ไม่ใช่ในทางกลับกัน นี่เป็นคำถามที่พบบ่อย ลิงค์นี้เชื่อมโยงไปยังหน้าเว็บเมื่อ 20 กว่าปีที่ผ่านมาซึ่งจะอธิบายรายละเอียดเพิ่มเติม และนี่เป็นคำถามที่เกิดขึ้นซ้ำแล้ว
tripleee

11

สำหรับ Mac ฉันไม่สามารถหา pgrep และ pkill ได้ทั้ง killall ทำงานได้ดังนั้นจึงเขียนสคริปต์ตัวย่อหนึ่งตัวที่เรียบง่าย: -

export pid=`ps | grep process_name | awk 'NR==1{print $1}' | cut -d' ' -f1`;kill $pid

หากมีวิธีการที่ง่ายกว่านี้กรุณาแชร์


1
ฮ่า ๆ. นี่คือคำสั่งที่บ้ากับงานดังกล่าว ไม่เป็นไร. คุณเรียกง่ายๆว่าหนึ่งบรรทัด? : D Simple is killall
m3nda

@ erm3nda :-) เห็นด้วย มองย้อนกลับไปมันดูบ้า ไม่สามารถจำได้ว่าทำไม killall ไม่ทำงานบน mac ของฉัน
Dhiraj

สิ่งนี้มีประโยชน์มากเมื่อคุณต้องการฆ่ากระบวนการ Java บางอย่างเช่น "jboss" ในกรณีนั้น killall ก็ไม่ได้ช่วยอะไร
ม.ค. M



5

ถูกต้องมากขึ้นจะเป็น:

export pid=`ps aux | grep process_name | awk 'NR==1{print $2}' | cut -d' ' -f1`;kill -9 $pid

1
ทำไมคุณexportถึงตัวแปรที่คุณจะใช้เพียงครั้งเดียวในกระบวนการเดียวกัน?
tripleee


3

ผมก็ถามตัวเองคำถามเดียวกัน แต่ปัญหามีคำตอบในปัจจุบันคือการที่พวกเขาไม่ได้ตรวจสอบความปลอดภัยในกระบวนการที่จะถูกฆ่าตายอย่างนั้น ... มันอาจนำไปสู่ความผิดพลาดที่น่ากลัว:) ... โดยเฉพาะถ้าหลายกระบวนการตรงกับรูปแบบ

ในฐานะที่เป็นข้อจำกัดความรับผิดชอบฉันไม่ใช่มืออาชีพและมีที่ว่างสำหรับการปรับปรุงอย่างแน่นอน

ดังนั้นฉันจึงเขียนสคริปต์ sh เล็กน้อย:

#!/bin/sh

killables=$(ps aux | grep $1 | grep -v mykill | grep -v grep)
if [ ! "${killables}" = "" ]
then
  echo "You are going to kill some process:"
  echo "${killables}"
else
  echo "No process with the pattern $1 found."
  return
fi
echo -n "Is it ok?(Y/N)"
read input
if [ "$input" = "Y" ]
then
  for pid in $(echo "${killables}" | awk '{print $2}')
  do
    echo killing $pid "..."
    kill $pid 
    echo $pid killed
  done
fi

2

ถ้าคุณเรียกใช้ GNOME คุณสามารถใช้การตรวจสอบระบบ (ระบบ -> การดูแล -> การตรวจสอบระบบ) เพื่อฆ่ากระบวนการอย่างที่คุณทำภายใต้ Windows KDE จะมีบางสิ่งที่คล้ายกัน


2

killคำสั่งเริ่มต้นยอมรับชื่อคำสั่งเป็นทางเลือกแทน PID ดูฆ่า (1) ปัญหาที่มักจะเกิดขึ้นคือbashให้บริการของตัวเองkillซึ่งยอมรับหมายเลขงานเช่นkill %1แต่ไม่ใช่ชื่อคำสั่ง สิ่งนี้จะขัดขวางคำสั่งเริ่มต้น หากฟังก์ชันการทำงานเดิมมีประโยชน์กับคุณมากกว่ารุ่นหลังคุณสามารถปิดใช้งานbashเวอร์ชันได้โดยโทร

enable -n kill

สำหรับดูข้อมูลเพิ่มเติมkillและenableรายการในทุบตี (1)


ฉันจะเปิดใช้งานการกระทำอีกครั้งได้enable -n killอย่างไร
Brethlosze

1
@hyprfrcbenable kill
The Vee



0

awk oneliner ซึ่งแยกวิเคราะห์ส่วนหัวของpsเอาต์พุตดังนั้นคุณไม่จำเป็นต้องสนใจหมายเลขคอลัมน์ (แต่ชื่อคอลัมน์) สนับสนุน regex ตัวอย่างเช่นเพื่อฆ่ากระบวนการทั้งหมดซึ่งชื่อที่ปฏิบัติการได้ (ไม่มีพา ธ ) มีคำว่า "firefox" ลอง

ps -fe | awk 'NR==1{for (i=1; i<=NF; i++) {if ($i=="COMMAND") Ncmd=i; else if ($i=="PID") Npid=i} if (!Ncmd || !Npid) {print "wrong or no header" > "/dev/stderr"; exit} }$Ncmd~"/"name"$"{print "killing "$Ncmd" with PID " $Npid; system("kill "$Npid)}' name=.*firefox.*
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.