Chấm dứt mọi quá trình nền


10

Tôi có một vài Stoppedquá trình nền.

kill $(jobs -p)kill `jobs -p`không có tác dụng

kill %1, kill %2v.v ... chấm dứt thành công các quy trình riêng lẻ

Làm thế nào tôi có thể giết mọi tiến trình nền bằng một lệnh?

Ngoài ra, tại sao hai lệnh đầu tiên không làm việc cho tôi?

Tôi đang chạy Linux Mint 15, 64 bit

Câu trả lời:


10

Khi họ đang chạy

Có vẻ như bạn chỉ có thể làm điều này với killvà đầu ra của jobs -p.

Thí dụ

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

Bây giờ tôi có 3 công việc giả đang chạy.

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

Giết tất cả chúng như vậy:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

Khẳng định tất cả đã biến mất.

$ jobs
$

Khi họ dừng lại

Nếu bạn có công việc bị dừng, không chạy, bạn làm điều này thay vào đó.

Thí dụ

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

OK để không giết chúng, nhưng đó là vì tín hiệu tiêu diệt không thể được xử lý bởi chính quá trình, nó đã dừng lại. Vì vậy, nói với hệ điều hành để giết chết thay thế. Đó là những gì a -9dành cho.

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

Cái đó tốt hơn.

$ jobs
$ 

Khi một số đang chạy và một số bị dừng lại

Nếu bạn có một túi hỗn hợp các quy trình trong đó một số quy trình bị dừng và một số đang chạy, bạn có thể thực hiện bước killđầu tiên theo sau là a kill -9.

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

Kéo dài thời gian một chút nếu bạn cần nhiều hơn để cho phép các quá trình tự dừng lại trước tiên.

Tín hiệu

Không phải HUP (-1) hoặc SIGTERM (-15) để giết sẽ thành công. Nhưng tại sao? Đó là bởi vì những tín hiệu này tốt hơn theo nghĩa là chúng đang bảo ứng dụng tự chấm dứt. Nhưng vì ứng dụng ở trạng thái dừng nên nó không thể xử lý các tín hiệu này. Vì vậy, khóa học duy nhất của bạn là sử dụng SIGKILL (-9).

Bạn có thể thấy tất cả các tín hiệu killcung cấp với kill -l.

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

Nếu bạn muốn tìm hiểu nhiều hơn về các tín hiệu khác nhau, tôi rất khuyến khích người ta hãy xem trang người đàn ông tín hiệu , man 7 signal.


Tại sao chúng ta có +biểu tượng cho quy trình đầu tiên và -biểu tượng cho quy trình thứ hai và không có biểu tượng trong quy trình thứ ba?
Ramesh

Tôi đã nhận được kết quả tương tự như bạn. Tuy nhiên tôi muốn terminatethay vì kill, vì tôi đã đọc nó an toàn hơn. Tôi đã thử kill -15 $(jobs -p), nhưng điều đó không có kết quả. Tôi đoán rằng các quy trình đã dừng chỉ có thể bị giết, nhưng sau đó một lần nữa kill %numberchấm dứt (các cá nhân) các quy trình đã dừng.
dùng49888

@Ramesh Các +-chỉ là các quá trình cuối cùng mà tôi chạm vào khi tôi thiết lập các ví dụ. Điều +đó có nghĩa là bất kỳ lệnh nào không bao gồm rõ ràng %#sẽ hành động theo lệnh đó. Dấu gạch ngang ( -) là lệnh thứ 2 đến lệnh cuối cùng mà tôi chạm vào.
slm

@ user49888 - kill -9 .. nên đã làm việc. các quá trình là gì? Họ là những quá trình không còn tồn tại hay mồ côi?
slm

1
@ user49888 - có nếu quá trình ở giữa một cái gì đó không có cơ hội để thực hiện bất kỳ việc dọn dẹp nào trước khi bị chấm dứt.
slm

2

Bạn có thể thử điều này.

for x in `jobs -p`; do kill -9 $x; done

Tuy nhiên, nếu bạn muốn chấm dứt quá trình, bạn có thể ban hành lệnh như,

for x in `jobs -p`; do kill -15 $x; done

Từ trang Wiki của Killlệnh,

Một quy trình có thể được gửi tín hiệu SIGTERM theo bốn cách (ID tiến trình là '1234' trong trường hợp này):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

Quá trình có thể được gửi tín hiệu SIGKILL theo ba cách:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

Như đã giải thích trong câu trả lời này , đây là sự khác biệt giữa chấm dứtgiết .

Tín hiệu kết thúc, SIGTERM , là tín hiệu có thể bị chặn trong một chương trình. Thông thường các quy trình có nghĩa là chạy trong nền sẽ bắt tín hiệu này và bắt đầu quá trình tắt máy, dẫn đến thoát sạch. Tín hiệu tiêu diệt, SIGKILL , không thể bị chặn. Khi điều này được gửi đến một quá trình, nó sẽ dẫn đến việc chấm dứt đột ngột chương trình đó.

Khi bạn tắt máy hoặc khởi động lại máy tính chẳng hạn, thường thì SIGTERM được gửi đến các tiến trình đang chạy trước tiên cho phép chúng thoát ra một cách sạch sẽ nếu chúng hỗ trợ. Sau đó, sau vài giây, SIGKILL được gửi đến các quy trình vẫn đang chạy để các tài nguyên đang sử dụng được giải phóng một cách cưỡng bức (ví dụ: các tệp đang sử dụng) và trình tự tắt có thể tiếp tục (ví dụ: ngắt kết nối các hệ thống tệp).


Điều này làm killmọi quá trình nền. Tuy nhiên, có cách nào để terminatehọ thay thế, vì tôi tin rằng an toàn hơn?
user49888

Nếu bạn muốn chấm dứt, bạn có thể sử dụng -15trong lệnh kill.
Ramesh

-15cũng sẽ không làm việc ở đây. Xem A.
slm

@Ramesh - 2 đoạn cuối không đúng. Một SIGTERM không được gửi (không phải ban đầu). Các quy trình được cố gắng dừng trước tiên thông qua các tập lệnh dừng / bắt đầu dịch vụ. Nếu đó là trường hợp số 9 được gửi đến quy trình thì với các quy trình đã dừng như trong ví dụ của OP, kill -9trong ví dụ của tôi sẽ không hoạt động.
slm

1

Ok, chơi xung quanh với điều này tôi thấy rằng khi bạn giết một công việc bị dừng lại (nơi việc thực thi đã bị tạm dừng nhưng không bị chấm dứt), thì nó sẽ không hoàn thành cho đến khi nó được đưa vào nền trước. Các chương trình thường được dừng lại bằng cách nhấn Ctrl- Ztrên thiết bị đầu cuối. Hầu hết các thiết bị đầu cuối gửi SIGSTOPtrong trường hợp này, nhưng tất nhiên cũng có những cách khác để gửi nó như với kill -STOPhoặc kill -19.

Đó là hành vi bình thường để chương trình không kết thúc ngay lập tức vì chương trình phải chạy để xử lý SIGTERMtín hiệu mặc định được gửi bởi kill. Hơn nữa, đôi khi sau khi bashgửi SIGTERMđến một quá trình nền, bằng cách nào đó nó đã dừng lại (mặc dù SIGTERMvẫn đang chờ xử lý).

Cách an toàn nhất để hoàn thành tất cả các công việc ( không cần dùng đến kill -9) trước tiên là gửi SIGTERMvới một bình thường kill, sau đó gửi SIGCONTđến bất kỳ công việc còn lại nào, ví dụ:

kill $(jobs -p)
kill -18 $(jobs -p)

Các SIGCONT( 18là số tín hiệu) sẽ mang lại bất kỳ việc chấm dứt vào tiền cảnh để họ có thể xử lý SIGTERMkhi họ bình thường.

Nếu tất cả các chương trình không kết thúc với điều này, thì có một vài tín hiệu khác mà bạn có thể thử mà thường làm cho quá trình kết thúc, trước khi dùng đến kill -9. Điều đầu tiên tôi khuyên là SIGHUPvì rất nhiều chương trình thường chặn các tín hiệu kết thúc khác đáp ứng SIGHUP. Điều này thường được gửi khi một thiết bị đầu cuối kiểm soát đóng, đặc biệt là nó được gửi khi một sshphiên ttykết thúc. Nhiều chương trình tương tác, chẳng hạn như hệ vỏ, sẽ không phản hồi với các tín hiệu chấm dứt khác nhưng sẽ xảy ra vì đây sẽ là vấn đề khiến chúng tiếp tục chạy sau khi sshphiên kết thúc (hoặc sau khi bất kỳ thiết bị đầu cuối điều khiển nào đóng). Để thử điều này bạn có thể như vậy

kill -1 $(jobs -p)
kill -18 $(jobs -p)

Tất nhiên, một lần nữa, bạn cần đảm bảo chương trình không bị dừng để có thể xử lý tín hiệu. Các tín hiệu kết thúc khác bạn có thể thử là SIGINT( kill -2) và SIGQUIT( kill -3). Nhưng tất nhiên lợi ích của việc thử toàn bộ phạm vi giảm dần và có thể dẫn đến một điều không thể tránh khỏi SIGKILL(aka kill -9).


Nếu bạn làm một man signalbạn có thể lấy tài liệu tham khảo để sao lưu này.
slm

Đây là một hình thức nhẹ nhàng hơn những gì A của tôi gợi ý. Có những trường hợp tôi đã gặp phải trong quá khứ, nơi điều này vẫn sẽ không dọn dẹp hoàn toàn mọi thứ vì vậy nếu bạn thực hiện điều này từ một tập lệnh, kill -9 ..phương thức sẽ hoạt động trong hầu hết các trường hợp. Điều này đôi khi sẽ để lại các quá trình treo xung quanh, do đó sẽ thất bại nhiều thời gian hơn. Đó là một sự đánh đổi bạn phải quyết định. Tốt hơn là nên mạnh tay và giết tất cả mọi thứ, mạo hiểm dữ liệu / dọn dẹp so với việc dọn dẹp nhẹ nhàng hơn, nhưng phải phân tích nhiều hơn khi giết chết của bạn ngày càng khắc nghiệt hơn.
slm

@slm, bạn nên tránh kill -9bất cứ khi nào có thể vì điều này chỉ cần rút phích cắm mà không cho chương trình cơ hội để dọn dẹp đúng cách. Tôi sẽ cập nhật với một số lựa chọn thay thế.
Graeme

Như tôi đã nói hương vị của bạn nhẹ nhàng hơn những gì tôi đề xuất, nó thuộc về những gì bạn đang cố gắng làm so với sẵn sàng chịu đựng từ góc độ rủi ro. Tôi đã sử dụng phương pháp của bạn cũng như của tôi. Cả hai đều đúng IMO. Ngoài ra a kill ..; sleep <time>; kill -18 ..; ngủ <thời gian>; giết -9 ... . Basically working up to the -9`.
slm

@slm, kill -18đây chắc chắn là thứ nên được sử dụng vì thông thường đã dừng công việc (và trong một số trường hợp có vẻ như bashbằng cách nào đó dừng chạy công việc trước khi gửi SIGTERM). Như đã thêm ở trên SIGHUPcũng đáng để thử vì nhiều chương trình không phản hồi với các chương trình khác sẽ đáp ứng điều này (thử với vỏ). Ngoài ra, vâng, nó không đáng giá như vậy SIGKILLcó lẽ là không thể tránh khỏi.
Graeme

0

Điều này sẽ chấm dứt tất cả các công việc trong shell hiện tại của bạn từng cái một:

while kill %; do :; done

Giải thích: %đề cập đến công việc cuối cùng trong danh sách, vì vậy nó sẽ lặp cho đến khi killtrả về giá trị khác không, điều đó có nghĩa là không còn công việc nào để chấm dứt.

Một cách tiếp cận khác có thể là gửi đầu tiên SIGTERM, sau đó SIGCONTđể công việc của bạn có thể tiếp tục và điều đầu tiên họ sẽ làm là nhận của bạn SIGTERM.

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(vì một số lý do tích hợp killlà lạ, vì vậy tôi đã sử dụng bên ngoài ở đây).

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.