linux: giết nhiệm vụ nền


194

Làm thế nào để tôi giết tác vụ nền được sinh ra cuối cùng trong linux?

Thí dụ:

doSomething
doAnotherThing
doB &
doC
doD
#kill doB
????

18
Làm thế nào điều này có thể không liên quan đến lập trình? Lập trình Bash không phải là lập trình?
flybywire

6
Đây là khu vực chồng chéo giữa SO và SU, nhưng tôi nghĩ nó phù hợp hơn ở đây trên SO. Tiêu chí của tôi để nghĩ theo cách này là nếu @flybywire thực hiện điều này trong một kịch bản, thì đó là lập trình. Nếu anh ta chỉ muốn làm điều đó từ dòng lệnh tôi sẽ nói nó thuộc về SU.
Bill the Lizard

10
Shell scripting là lập trình quá.
cletus

Câu trả lời:


234

Có một biến đặc biệt cho điều này trong bash:

kill $!

$! mở rộng tới PID của quá trình cuối cùng được thực hiện trong nền.


68
@ polm23; không, ^Zkhông phải công việc nền, nó dừng lại. Sau đó bg, 'nền' thực tế (tiếp tục thực hiện trong nền) và sau đó $!hoạt động như mong đợi.
falstro

Giả sử ????là viết tắt của một hoặc nhiều lệnh được thực thi sau khi hủy, nếu bất kỳ lệnh nào phụ thuộc vào công việc được thực hiện bởi quá trình nền, hãy chú ý đến bất kỳ tác vụ dọn dẹp hoặc hoàn thiện nào mà quá trình nền có thể thực hiện trong trình xử lý tín hiệu sau nhận được tín hiệu (bẫy). Tốt nhất để thêm một wait(có lẽ là theo a synchoặc thậm chí a sleep <n>) ngay trước lệnh đầu tiên của bất kỳ lệnh 'phụ thuộc' nào như vậy.
ack

2
Để hoàn thành: Vì một% duy nhất cũng đề cập đến công việc hiện tại, bạn có thể giết công việc đã dừng (^ z) bằng "kill%". Tôi sử dụng nó gần như luôn luôn sau ^ z.
t3o

Điều này chỉ hoạt động nếu bạn đã bật chức năng kiểm soát công việc, chỉ được bật theo mặc định trong các vỏ tương tác (mặc dù vì bạn đang đề cập đến việc sử dụng ctrl-z Tôi đoán bạn cũng đang đề cập đến việc sử dụng trình bao tương tác) - nhưng điều này đã được nêu ra trong các câu trả lời khác ở đây, không chắc tại sao đây là "cho sự hoàn chỉnh" :)
falstro 13/03/19

289

Bạn có thể giết theo số công việc. Khi bạn đặt một tác vụ trong nền, bạn sẽ thấy một cái gì đó như:

$ ./script &
[1] 35341

Đó [1]là số công việc và có thể được tham chiếu như:

$ kill %1
$ kill %%  # Most recent background job

Để xem danh sách các số công việc, sử dụng jobslệnh. Thêm từ man bash:

Có một số cách để đề cập đến một công việc trong vỏ. Nhân vật %giới thiệu một tên công việc. Số công việc ncó thể được gọi là %n. Một công việc cũng có thể được gọi là sử dụng tiền tố của tên được sử dụng để bắt đầu nó hoặc sử dụng một chuỗi con xuất hiện trong dòng lệnh của nó. Ví dụ, %ceđề cập đến một cecông việc đã dừng lại . Nếu một tiền tố phù hợp với nhiều công việc, bash báo lỗi. %?ceMặt khác, sử dụng để chỉ bất kỳ công việc nào chứa chuỗi cetrong dòng lệnh của nó. Nếu chuỗi con khớp với nhiều công việc, bash báo lỗi. Các biểu tượng %%%+đề cập đến khái niệm của shell về công việc hiện tại, đây là công việc cuối cùng dừng lại khi nó ở phía trước hoặc bắt đầu trong nền. Các công việc trước đây có thể được tham chiếu bằng cách sử dụng %-. Trong đầu ra liên quan đến các công việc (ví dụ: đầu ra của lệnh công việc), công việc hiện tại luôn được gắn cờ với a +và công việc trước đó với a -. Một đơn %(không có đặc điểm công việc đi kèm) cũng đề cập đến công việc hiện tại.


Đối với hồ sơ, tôi nghĩ rằng điều này chỉ hoạt động nếu kiểm soát công việc được kích hoạt. Mặc dù tôi nghĩ rằng bạn có thể bật nó trong các tập lệnh ( set -m), nhưng nó dành cho sử dụng tương tác. Xem stackoverflow.com/questions/690266/ cũng như
falstro

9
Biểu tượng rất hữu ích, những %1%%đặc biệt. Một số thứ không chết trên Ctrl-C, vì vậy bạn cần Ctrl-Z và sau đó kill -9 %%. Một ví dụ mà tôi thấy nó hữu ích là: while true; do mplayer <some unstable online radio>; date >> restarts.log; done- Ctrl-C sẽ đưa bạn đến vòng lặp tiếp theo. Trước khi tôi phải làm pshoặc có thể jobs -l, và sau đó gõ lại PID, điều này thật tẻ nhạt.
Tomasz Gandor

Có một cho tất cả các công việc?
CMCDragonkai

3
@TomaszGandor Đó là lý do tại sao bạn có thể muốn thay thế while truebằng while sleep 1. Điều này sẽ cung cấp cho bạn một độ trễ ngắn trước khi khởi động lại nếu bạn có thể sống với điều đó và nếu bạn nhấn ctrl-c hai lần, lần thứ hai sẽ làm gián đoạn giấc ngủ, kết thúc nó bằng một lối thoát khác không và thoát ra khỏi vòng lặp.
falstro

45

Lệnh sau cung cấp cho bạn một danh sách tất cả các quy trình nền trong phiên của bạn, cùng với pid. Sau đó bạn có thể sử dụng nó để giết quá trình.

jobs -l

Ví dụ sử dụng:

$ sleep 300 &
$ jobs -l
[1]+ 31139 Running                 sleep 300 &
$ kill 31139

25

Điều này sẽ giết tất cả các quá trình nền:

jobs -p | xargs kill -9

1
Đây là những gì tôi sử dụng trước đây, nhưng kill -9 %%ít gõ hơn :)
Tomasz Gandor

4
@TomaszGandor Điều đó sẽ chỉ giết công việc hiện tại tức là công việc cuối cùng dừng lại ở tiền cảnh hoặc bắt đầu ở chế độ nền. Lệnh trong câu trả lời sẽ giết TẤT CẢ công việc.
cắn


2
skill doB

skill là một phiên bản của lệnh kill cho phép bạn chọn một hoặc nhiều quy trình dựa trên một tiêu chí nhất định.


0

Bạn cần pid của nó ... sử dụng "ps -A" để tìm thấy nó.


0

Đây là một câu trả lời ngoài chủ đề, nhưng, đối với những người quan tâm, nó có thể có giá trị.

Như trong câu trả lời của @John Kugelman,% có liên quan đến đặc tả công việc. Làm thế nào để tìm thấy hiệu quả? sử dụng lệnh & mô hình ít hơn , dường như con người sử dụng ít máy nhắn tin hơn (không chắc chắn), trong kiểu bash man &% thì gõ Enter sẽ chỉ hiển thị các dòng có chứa '%', để đặt lại tất cả, nhập &. sau đó nhập.


-3

Chỉ cần sử dụng lệnh killall:

tên nhiệm vụ

để biết thêm thông tin và các tùy chọn nâng cao hơn, hãy nhập "man killall".


4
Tôi nghĩ killall hơi hung dữ khi bạn thực sự có quyền truy cập dễ dàng vào PID. Và nguy hiểm nữa, đặc biệt là nếu bạn đã root
Dave Vogt

3
Không hữu ích lắm, nếu bạn phải killall pythonhoặc killall java, trong khi có một cái gì đó hữu ích đang chạy ở mọi nơi trong hệ thống.
Tomasz Gandor
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.