จะทำอย่างไรเมื่อ Ctrl + C ไม่สามารถฆ่ากระบวนการได้


171

Ctrl+ Cไม่ทำงานเพื่อฆ่ากระบวนการปัจจุบันเสมอ (ตัวอย่างเช่นหากกระบวนการนั้นไม่ว่างในการดำเนินงานเครือข่ายบางอย่าง) ในกรณีนี้คุณเพิ่งเห็น "^ C" โดยเคอร์เซอร์ของคุณและไม่สามารถทำอะไรได้อีกมาก

อะไรคือวิธีที่ง่ายที่สุดในการบังคับให้กระบวนการนั้นตายในตอนนี้โดยไม่สูญเสียเครื่อง?

สรุปคำตอบ: โดยปกติคุณสามารถCtrl+ Zเพื่อทำให้กระบวนการเข้าสู่โหมดสลีปแล้วทำkill -9 _process-pid_ที่ซึ่งคุณพบ pid ของกระบวนการด้วยpsและเครื่องมืออื่น ๆ บนBash (และเปลือกหอยอื่น ๆ ) คุณสามารถทำkill -9 %1(หรือ '% N' โดยทั่วไป) ซึ่งทำได้ง่ายกว่า หากCtrl+ Zใช้งานไม่ได้คุณจะต้องเปิดเทอร์มินัลอื่นและฆ่าจากที่นั่น


screenจะเป็นทางออกที่เป็นไปได้ช่วยให้คุณสามารถสร้างหน้าต่างใหม่และkillกระบวนการจากที่นั่น
Bobby

2
สมมติว่าคุณมีอยู่แล้วในหน้าจอ :)
ดัสตินบอสเวลล์

คำตอบ:


119

เพื่อให้เข้าใจถึงสาเหตุที่Ctrl+ Cใช้งานไม่ได้จะเป็นประโยชน์อย่างมากที่จะเข้าใจว่าเกิดอะไรขึ้นเมื่อคุณกด:

เชลล์ส่วนใหญ่ผูกCtrl+ Cเพื่อ "ส่งสัญญาณSIGINTไปยังโปรแกรมที่ทำงานในเบื้องหน้า" คุณสามารถอ่านเกี่ยวกับสัญญาณต่าง ๆ ผ่านสัญญาณคน :

 SIGINT        2       Term    Interrupt from keyboard

โปรแกรมสามารถละเว้นสัญญาณนั้นเนื่องจากสามารถละเว้นSIGTSTP ได้เช่นกัน:

 SIGTSTP   18,20,24    Stop    Stop typed at tty

(ซึ่งเป็นสิ่งที่เชลล์ส่วนใหญ่ทำเมื่อคุณกดCtrl+ Zซึ่งเป็นสาเหตุที่ไม่รับประกันว่าจะทำงานได้)

มีสัญญาณบางอย่างที่กระบวนการไม่สามารถข้ามได้: SIGKILL , SIGSTOPและสัญญาณอื่น ๆ คุณสามารถส่งสัญญาณเหล่านี้ผ่านคำสั่งkill ดังนั้นเพื่อฆ่ากระบวนการแฮงค์ / ซอมบี้ของคุณเพียงแค่ค้นหาID กระบวนการ (PID) ตัวอย่างเช่นใช้pgrepหรือpsจากนั้นkill:

 % kill -9 PID

13
คำพูดเพียง ระวังว่า "zombie" นั้นเป็นกระบวนการทางเทคนิคและมันไม่เหมือนกับสิ่งที่คุณหมายถึงที่นี่ด้วย "zombieying" (กระบวนการที่สิ้นสุดซึ่งไม่ได้รอ () - ed โดยผู้ปกครองอยู่ในสถานะ zombie ( Z) ในกรณีนี้มันไม่สามารถจัดการสัญญาณได้อีกต่อไป)
Stéphane Gimenez

อนิจจาบางครั้ง ctrl + c, ctrl + z และ ctrl + \ ทั้งหมดไม่ทำอะไรเลยและกระบวนการกำลังดำเนินการเลิกทำ sudo (อนุญาตโดยไม่ใช้รหัสผ่าน) ดังนั้นคุณจึงไม่สามารถส่งสัญญาณไปยังกระบวนการได้
Michael

112

หากCtrl+ C(SIGINT) ใช้งานไม่ได้ให้ลองCtrl+ \(SIGQUIT) จากนั้นลองCtrl+ Z(SIGTSTP) หากสิ่งนั้นส่งคืนคุณให้กับ shell prompt ให้ทำkillตาม ID กระบวนการ (เริ่มต้นที่สัญญาณ SIGTERM ซึ่งคุณสามารถระบุด้วยkill -TERM. ในเปลือกหอยบางอย่างที่คุณอาจจะไม่สามารถที่จะใช้%1ในการอ้างถึงกํา.) หากไม่ได้ทำงานให้ไปที่ขั้วหรือ SSH เซสชั่นอื่นและทำkillหรือkill -TERMบน ID กระบวนการ เท่านั้นเป็นที่พึ่งสุดท้ายที่คุณควรทำkill -KILLหรือที่รู้จักkill -9ในขณะที่มันไม่ให้กระบวนการโอกาสที่จะยกเลิกเรียบร้อยซิงค์ไฟล์เปิดลบไฟล์ชั่วคราวเชื่อมต่อเครือข่ายใกล้ชิด ฯลฯ


32

กด Ctrl-Z เพื่อระงับโปรแกรมและวางไว้ในพื้นหลัง :

Suspend the program currently running and put it in the background.
This does not stop the process as it does in VMS!

(กู้คืนสู่เบื้องหน้าอีกครั้งโดยใช้fg)

จากนั้นคุณสามารถkillหรือkill -9ได้รับรหัสกระบวนการ (คุณได้รับจากps a)


13
ด้วยการทุบตีคุณสามารถkill $!เป็น$!ตัวแปรพิเศษที่มี pid ของโปรแกรมพื้นหลังล่าสุด
Lloeki

@loeki ไม่ทำงานสำหรับฉัน (อย่างน้อยก็ไม่น่าเชื่อถือ) ฉันต้องbgหนึ่งครั้งก่อนที่ตัวแปรจะได้รับค่าที่กำหนด
Daniel Beck

2
@Daniel ถูกต้อง มันเป็นอย่างที่ฉันบอกว่ากระบวนการพื้นหลังครั้งล่าสุดจึงต้องการbgทันทีหลังจาก Ctrl + Z มันถูกระงับเพียง
Lloeki

2
หมายเหตุ: นี่ไม่ใช่แค่การหลอกลวงการใช้psเอาต์พุต (หรือkillall) มีความเสี่ยงมากหากคุณมีหลายกระบวนการที่ใช้ชื่อเดียวกัน ps -e -o pid,commandจะให้ pid + args เต็มไม่ใช่แค่ชื่อโปรแกรม แต่อีกครั้งอาจไม่เพียงพอที่จะแยกแยะ ในทางตรงกันข้าม$!เป็นที่นิยมอย่างแน่นอน
Lloeki

1
@loeki ฉันไม่เห็นด้วย ตัวอย่างบรรทัดเอาต์พุตจากps aบนระบบของฉัน: 27721 s000 T 0:00.09 topคุณมีTอินสแตนซ์ของคำสั่งเดียวกัน ( top) ที่ระงับไว้กี่รายการ ( ) คุณใช้ tty ( s000) เดียวกันหรือไม่
Daniel Beck

30

ดูลิงค์นี้เช่นกัน

Ctrl+ Z: หยุดกระบวนการชั่วคราว

Ctrl+ C: ขอให้ปิดกระบวนการอย่างสุภาพ

Ctrl+ \: สังหารกระบวนการที่อยู่เบื้องหน้าอย่างไร้ความปราณี


"ctrl"+ "\"ไม่ทำงานสำหรับฉัน
เบ็

13

โดยปกติแล้วคุณยังสามารถหยุดกระบวนการ ( Ctrl+ Z) kill -9และจากนั้นใช้ สำหรับkill -9คุณต้องมีPID ของกระบวนการก่อน สำหรับงานพื้นหลังkill -9 %1เป็นวิธีที่ง่ายที่สุดที่จะทำมัน - jobsถ้าคุณไม่แน่ใจว่าเป็นจำนวนของงานพื้นหลังที่คุณต้องการที่จะฆ่ารัน

หรือคุณสามารถค้นหา ID กระบวนการด้วย

ps

จากนั้นคุณสามารถเรียกใช้

kill -9 <Appropriate PID from ps output>

5

วิธีที่ง่ายกว่าสำหรับ Bash (และ shell อื่น ๆ ?) คือ:

Ctrl-z      followed by     kill -9 %1

โดยที่ '% 1' หมายถึงหมายเลขงานที่จะถูกฆ่า อาจเป็น '% 2' (หรืออย่างอื่น) หากคุณมีงานอื่น ๆ ที่กำลังนอนหลับอยู่ คุณสามารถดูหมายเลขงานที่เป็นเมื่อคุณกด Ctrl-z:

[1]+  Stopped                 <process name>

โปรดทราบว่า 'kill' เป็นเวอร์ชันการฆ่าของเชลล์ไม่ใช่ / bin / kill


4

1) ถ้าคุณอยู่บนคอนโซลและในโหมดผู้ใช้หลายคนคุณสามารถกด CTRL-ALT-Fn และเข้าสู่ระบบบนหน้าจออื่นใช้ps -ef | grep <myprocessname>หรือpidof <myprocessname>จากนั้นฆ่ากระบวนการ -9 ด้วยหมายเลข ID

2) หากคุณเชื่อมต่อจากระยะไกลให้ทำเช่นเดียวกันผ่านเทอร์มินัลเซสชันอื่น

นอกจากนี้คุณยังสามารถทำให้ชีวิตง่ายขึ้นด้วยการติดตั้งhtopซึ่งเป็นรุ่นเอนกประสงค์ด้านบนที่ช่วยให้คุณสามารถฆ่ากระบวนการทำงานที่เลือกไว้ distros ส่วนใหญ่มี htop ใน repo

3) หากคุณเพิ่งติดค้างในเซสชัน hang ssh (ไปยังระบบอื่นเช่น) ลองกด tilde (~) ซึ่งเป็นปุ่ม escape แล้วกด CTRL-Z เพื่อกลับไปที่เซสชันโฮสต์จากนั้นคุณ สามารถฆ่ากระบวนการ ssh ที่ติดอยู่หรือรอให้หมดเวลาซึ่งงัวส่วนใหญ่ทำหลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่ง


0

หากคุณกำลังใช้ tmux หรือหน้าจอและไม่มีงานใด ๆ ที่กล่าวมาข้างต้นคุณยังคงสามารถฆ่าบานหน้าต่างได้จาก<prefix> xนั้นกระบวนการก็จะถูกฆ่าเช่นกัน


0

อาจมีชุดกับดักที่มี SIGINT (2) ใน / etc / profile ของคุณ หากเป็นเช่นนั้นให้ลบออก ออกจากระบบและกลับเข้าสู่ระบบและคุณควรจะดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.