Phải làm gì khi Ctrl + C không thể giết quá trình?


171

Ctrl+ Ckhông phải lúc nào cũng hoạt động để giết tiến trình hiện tại (ví dụ: nếu quá trình đó bận trong một số hoạt động mạng nhất định). Trong trường hợp đó, bạn chỉ thấy "^ C" bằng con trỏ của mình và không thể làm gì khác.

Cách dễ nhất để buộc quá trình đó chết bây giờ mà không mất thiết bị đầu cuối của tôi là gì?

Tóm tắt các câu trả lời: Thông thường, bạn có thể Ctrl+ Zđặt quá trình vào chế độ ngủ, sau đó thực hiện kill -9 _process-pid_, nơi bạn tìm thấy quy trình với ps và các công cụ khác. Trên Bash (và có thể các shell khác), bạn có thể thực hiện kill -9 %1(hoặc '% N' nói chung) dễ dàng hơn. Nếu Ctrl+ Zkhông hoạt động, bạn sẽ phải mở một thiết bị đầu cuối khác và giết từ đó.


screensẽ là một giải pháp khả thi, cho phép bạn tạo một cửa sổ mới và killquá trình từ đó.
Bobby

2
giả sử bạn đã ở trong màn hình :)
Dustin Boswell

Câu trả lời:


119

Để hiểu vấn đề tại sao Ctrl+ Ckhông hoạt động, rất hữu ích để hiểu những gì xảy ra khi bạn nhấn nó:

Hầu hết các shell liên kết Ctrl+ Cđể "gửi tín hiệu SIGINT đến chương trình hiện đang chạy ở nền trước". Bạn có thể đọc về các tín hiệu khác nhau thông qua tín hiệu man :

 SIGINT        2       Term    Interrupt from keyboard

Các chương trình có thể bỏ qua tín hiệu đó, vì chúng cũng có thể bỏ qua SIGTSTP :

 SIGTSTP   18,20,24    Stop    Stop typed at tty

(Đó là những gì hầu hết các shell làm khi bạn nhấn Ctrl+ Z, đó là lý do tại sao nó không được đảm bảo để hoạt động.)

Có một số tín hiệu mà quy trình không thể bỏ qua: SIGKILL , SIGSTOP và một số tín hiệu khác. Bạn có thể gửi các tín hiệu này thông qua lệnh kill . Vì vậy, để tiêu diệt quá trình treo / thây ma của bạn, chỉ cần tìm ID tiến trình (PID). Ví dụ: sử dụng pgrephoặc pssau killđó:

 % kill -9 PID

13
Một nhận xét đơn thuần. Coi chừng "zombie" về mặt kỹ thuật là một trạng thái quá trình và nó không giống như "zombie" ở đây. (Một quá trình kết thúc chưa được chờ đợi () - do cha mẹ của nó ở Ztrạng thái zombie ( ). Trong trường hợp này, nó không thể xử lý tín hiệu nữa.)
Stéphane Gimenez

than ôi, đôi khi ctrl + c, ctrl + z và ctrl + \ tất cả không làm gì cả và quá trình đang chạy hoàn tác sudo (được phép không có mật khẩu) để bạn không thể gửi tín hiệu đến quy trình.
Michael

112

Nếu Ctrl+ C(SIGINT) không hoạt động, hãy thử Ctrl+ \(SIGQUIT). Sau đó thử Ctrl+ Z(SIGTSTP). Nếu điều đó đưa bạn trở lại dấu nhắc shell, hãy thực hiện killID tiến trình. (Điều này mặc định là tín hiệu SIGTERM mà bạn có thể chỉ định kill -TERM. Trong một số shell, bạn có thể sử dụng %1để tham chiếu tới PID.) Nếu điều đó không hoạt động, hãy chuyển đến một thiết bị đầu cuối hoặc phiên SSH khác và thực hiện killhoặc kill -TERMtrên xử lý ID. Chỉ như là một phương sách cuối cùng bạn nên làm kill -KILL, aka kill -9, vì nó không cung cấp cho quá trình này bất kỳ cơ hội để hủy bỏ sạch sẽ, đồng bộ tập tin mở của nó, loại bỏ tập tin tạm thời của nó, kết nối mạng gần vv


32

Nhấn Ctrl-Z để tạm dừng chương trình và đặt nó vào nền :

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

(Khôi phục lại tiền cảnh một lần nữa bằng cách sử dụng fg)

Sau đó, bạn có thể killhoặc kill -9nó, đưa ra ID tiến trình của nó (bạn lấy từ đó ps a).


13
Với bash bạn có thể kill $!, như $!là một biến đặc biệt chứa pid của chương trình nền cuối cùng.
Lloeki

@Lloeki Không làm việc cho tôi (ít nhất là không đáng tin cậy). Tôi phải bgmột lần trước khi biến được giá trị được gán.
Daniel Beck

2
@Daniel, đúng rồi. Như tôi đã nói quá trình nền sau cùng , do đó cần bgngay sau khi Ctrl + Z, nó chỉ bị treo.
Lloeki

2
Lưu ý: đây không chỉ là một mẹo, sử dụng psđầu ra (hoặc killall) khá rủi ro nếu bạn có nhiều quy trình có cùng tên đang chạy. ps -e -o pid,commandsẽ cung cấp pid + args đầy đủ, không chỉ tên chương trình, mà một lần nữa có thể không đủ để phân biệt đối xử. Ngược lại $!là một hit chắc chắn.
Lloeki

1
@Lloeki tôi không đồng ý. Ví dụ dòng đầu ra từ ps atrên hệ thống của tôi: 27721 s000 T 0:00.09 topCó bao nhiêu trường hợp bị treo ( T, tôi nghĩ) của cùng một lệnh ( top) mà bạn đã chạy trong cùng một tty ( s000)?
Daniel Beck

30

Xem liên kết này là tốt.

Ctrl+ Z: tạm dừng một quá trình.

Ctrl+ C: lịch sự yêu cầu quá trình đóng cửa ngay bây giờ.

Ctrl+ \: giết không thương tiếc quá trình hiện đang ở phía trước


"ctrl"+ "\"không làm việc cho tôi
Benyamin Jafari

13

Thông thường, bạn vẫn có thể dừng quá trình ( Ctrl+ Z) và sau đó sử dụng kill -9. Đối với kill -9, bạn cần quá trình PID đầu tiên. Đối với các công việc nền, kill -9 %1là cách dễ nhất để thực hiện - nếu bạn không chắc chắn số lượng công việc nền mà bạn muốn giết, hãy chạy jobs.

Ngoài ra, bạn có thể tìm ID tiến trình với

ps

Sau đó bạn có thể chạy

kill -9 <Appropriate PID from ps output>

5

Một giải pháp đơn giản hơn cho Bash (và các shell khác?) Là làm:

Ctrl-z      followed by     kill -9 %1

trong đó '% 1' chỉ số công việc bị giết. Nó có thể là '% 2' (hoặc một cái gì đó khác) nếu bạn đã có công việc khác đang ngủ. Bạn có thể xem số công việc đó là gì khi bạn nhấn Ctrl-z:

[1]+  Stopped                 <process name>

Lưu ý rằng 'kill' là phiên bản giết của shell, không phải / bin / kill.


4

1) Nếu bạn đang ở trên bảng điều khiển và ở chế độ nhiều người dùng, bạn có thể nhấn CTRL-ALT-Fn và đăng nhập trên màn hình khác, sử dụng ps -ef | grep <myprocessname>hoặc pidof <myprocessname>sau đó giết -9 quá trình theo số ID.

2) Nếu bạn được kết nối từ xa, hãy thực hiện tương tự thông qua một phiên cuối khác.

Bạn cũng có thể làm cho cuộc sống dễ dàng hơn một chút bằng cách cài đặt htop , đây là phiên bản linh hoạt hơn của đầu cho phép bạn tiêu diệt một cách có chọn lọc các quy trình đang chạy. Hầu hết các distro có htop trong một repo.

3) nếu bạn chỉ bị kẹt trong phiên treo ssh (chẳng hạn với hệ thống khác), hãy thử nhấn dấu ngã (~), đó là phím thoát, sau đó nhấn CTRL-Z để quay lại phiên máy chủ, sau đó bạn có thể giết quá trình ssh bị kẹt hoặc chờ cho đến khi hết thời gian, điều mà hầu hết các ngưỡng đều làm sau một thời gian không hoạt động.


0

Nếu bạn đang sử dụng tmux hoặc màn hình, và không có cách nào ở trên, bạn vẫn có thể giết khung <prefix> xđó, thì quá trình cũng bị hủy.


0

Có thể có một cái bẫy được đặt với SIGINT (2) trong hồ sơ / etc / của bạn. Nếu vậy, loại bỏ nó. Đăng xuất và đăng nhập lại và bạn sẽ tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.