Giết nhiều phiên bản của một tiến trình đang chạy bằng một lệnh


75

Giả sử tôi có một nghìn hoặc nhiều phiên bản của bất kỳ quá trình nào (ví dụ vi:) chạy. Làm thế nào để tôi giết tất cả chúng trong một lần bắn / một lệnh một dòng / một lệnh?


3
Không rõ hệ thống nào bạn dự định làm việc này. Ví dụ, trên Linux tôi sử dụng pkilltừ procpsgói.
Deer Hunter

Câu hỏi đã được hỏi từ một quan điểm chung. Tôi chỉ biết hai quá trình như killall và thông qua awk / sed. Nhưng tôi muốn biết liệu có những cách khác để đạt được điều này. Nếu nó được thực hiện khác nhau trong các hệ thống khác nhau, thì tôi muốn biết cái gì trong đó. Nó rất cồng kềnh với google, thay vào đó tôi nghĩ đến việc thảo luận với tất cả các bạn có kinh nghiệm.
Hiệp sĩ bóng đêm

Câu trả lời:


97

Có chuyện gì với người già,

for pid in $(ps -ef | grep "some search" | awk '{print $2}'); do kill -9 $pid; done

Có nhiều cách để làm điều đó hiệu quả hơn,

for pid in $(ps -ef | awk '/some search/ {print $2}'); do kill -9 $pid; done

và các biến thể khác, nhưng ở cấp độ cơ bản, nó luôn hoạt động với tôi.


1
Lên bình chọn, chỉ biết biến thể đầu tiên. Thứ hai có vẻ hiệu quả hơn, cảm ơn bạn.
Hiệp sĩ bóng đêm

5
@TheDarkKnight Vấn đề với phương pháp này là bạn thường giết nhiều hơn bạn dự định. Viết một tin nhắn đáng tin cậy của một số người tìm kiếm là khó khăn. Trong Linux, sử dụng pkill , xử lý hầu hết các phần tinh tế.
Gilles

Tôi không chắc nó khó đến thế, nếu bạn sau một nhị phân cụ thể thì nó có thể khá đáng tin cậy. Tôi luôn luôn chạy nó như một echo kill -9 $pidlần đầu tiên vì vậy tôi biết những gì tôi đang nhận được. Tôi không chắc AIX có pkill, đó là bánh mì và bơ UNIX của tôi. Và nó thực sự đủ tệ để bị bỏ phiếu - lẻ.
EightBitTony

1
Trừ khi thực sự cần thiết, bạn nên gửi SIGTERM quá trình thay vì SIGKILL.

Tôi nên thêm rằng 2 phương thức này sẽ không hoạt động trong tất cả các hệ vỏ, ví dụ như nó không hoạt độngcsh
không phải là trình tự tiếp theo

38

Sử dụng killall,

killall vi

Điều này sẽ giết tất cả các lệnh có tên 'vi'

Bạn cũng có thể thêm tín hiệu, ví dụ SIGKILL

killall -9 vi


Đúng vậy, bạn cũng có thể thêm tín hiệu bạn muốn, nhưkillall -9 vi
Hola Soy Edu Feliz Navidad

1
Tôi không nghĩ killall là nguyên nhân của nó: Giết bằng tệp chỉ hoạt động đối với các tệp thực thi được giữ mở trong khi thực thi, tức là các tệp thực thi không tinh khiết không thể bị giết theo cách này. Việc gõ tên killall có thể không có tác dụng mong muốn đối với các hệ thống không phải là Linux, đặc biệt là khi được thực hiện bởi một người dùng đặc quyền. Điều gì sẽ xảy ra nếu tôi đang cố gắng xóa rất nhiều phiên bản của một quy trình không phải linux? killall -w không phát hiện nếu một quá trình biến mất và được thay thế bằng một quy trình mới với cùng một PID giữa các lần quét. Nếu các quy trình thay đổi tên của họ, killall có thể không khớp chính xác với chúng.
Hiệp sĩ bóng đêm

13
Xin lưu ý rằng điều này chỉ hoạt động trên Linux và BSD. Trên Solaris và một số hệ thống khác killallthực hiện chính xác những gì mà tên cho thấy ... nó giết chết quá trình khởi tạo.
Bobby

2
Trên AIX, nó "hủy bỏ tất cả các quy trình mà bạn đã bắt đầu, ngoại trừ những quy trình sản xuất quy trình killall."
EightBitTony

31

pkilllà những gì tôi khuyên, nếu nó khả dụng ( Linux , FreeBSD , NetBSD , OpenBSD , Solaris ). Bạn có thể chỉ định các quy trình theo tên lệnh, theo dòng lệnh đầy đủ hoặc các tiêu chí khác. Ví dụ, pkill vigiết tất cả các chương trình có tên lệnh chứa chuỗi con vi. Để giết chỉ các quá trình được gọi vi, sử dụng pkill -x vi. Để chỉ giết các tiến trình được gọi vivới một đối số cuối cùng kết thúc .conf, hãy sử dụng pkill -fx 'vi.*\.conf'.

Để xem danh sách các PID pkillsẽ gửi tín hiệu đến, hãy sử dụng pgrep, có cùng một cú pháp ngoại trừ việc nó không chấp nhận tên hoặc số tín hiệu. Để xem thêm thông tin về các quy trình này, hãy chạy

ps -p "$(pgrep …)"

Trong Linux, bạn cần ps -p $(pgrep -d, …)thay thế (đó là một lỗi: Linux pskhông tuân thủ POSIX).

Một cách phổ biến khác để xác định các quy trình cần hủy là các quy trình có một tệp nhất định mở (có thể là quy trình thực thi của quy trình). Bạn có thể liệt kê những thứ này với fuser; sử dụng fuser -kđể gửi cho họ một tín hiệu. Ví dụ, fuser -k /usr/bin/findgiết tất cả các hiệu ứng đang chạy của find.

Nếu có một quy trình chạy trốn liên tục, bạn có thể cần phải giết toàn bộ nhóm quy trình cùng một lúc. Một nhóm quy trình được xác định bởi tiêu cực của người lãnh đạo của nó, đó là quá trình tổ tiên của tất cả các quy trình trong nhóm. Để xem nhóm quy trình mà một quy trình thuộc về, hãy chạy ps -o pgid(cộng với bất kỳ tùy chọn nào để chọn (các) quy trình sẽ hiển thị). Nếu bạn xác định rằng bạn muốn giết thủ lĩnh nhóm quy trình 1234 và tất cả các con của nó, hãy chạy kill -1234hoặc kill -HUP -1234hoặc bất kỳ tín hiệu nào khác.

Nếu bạn không thể tìm thấy một cách tốt hơn, hãy sử dụng psvới các tùy chọn phù hợp để liệt kê tất cả các quy trình và lọc nó bằng grephoặc một số lệnh lọc văn bản khác. Cẩn thận không vô tình khớp với các quy trình khác đang chạy một lệnh có tên tương tự hoặc với một đối số có chứa tên đó. Ví dụ:

kill $(ps -o pid -o comm | awk '$2 == "vi" {print $1}')

Hãy nhớ rằng chính lệnh grephoặc awklệnh của bạn có thể được liệt kê trong psđầu ra ( psvà lệnh lọc được bắt đầu song song, do đó, liệu nó có hiển thị hay không phụ thuộc vào thời gian). Điều này đặc biệt quan trọng nếu các đối số lệnh được bao gồm trong psđầu ra.


Cảm ơn rất nhiều, điều này thực sự tuyệt vời. Những gì bạn đã đưa ra là một loại hướng dẫn. Cảm ơn một lần nữa. Được bình chọn
Hiệp sĩ bóng đêm

6

pkillở đây rất đẹp Bạn có thể cung cấp cho nó rất nhiều tham số để tinh chỉnh mẫu.


Không có sẵn trên tất cả các UNIX và không đề cập đến một hệ điều hành UNIX hoặc UNIX cụ thể trong câu hỏi.
EightBitTony

@EightBitTony pkillcó sẵn trên Linux, BSD và Solaris - afaik. Vì vậy, nó có một sự lây lan lớn hơn killall.
Nils

Tôi đồng ý, nhưng killall thậm chí còn có vấn đề hơn bởi vì có nhiều công cụ có cùng tên, có vẻ như có hành vi khác nhau đáng kể. Tôi cũng không thích câu trả lời của killall. pkill không tồn tại trên AIX hoặc HP-UX và mặc dù một số người muốn tin, vẫn có một nền tảng đáng kể dựa trên UNIX không phải Linux trên thế giới.
EightBitTony

1
@EightBitTony đó là lý do tại sao câu trả lời của bạn là câu trả lời được chấp nhận. Nhưng tôi sẽ không sử dụng nó trên Solaris (cũng là Unix).
Nils

6

Cách dễ nhất để làm là trước tiên hãy kiểm tra xem bạn có nhận được ID quy trình đúng với:

pgrep -f [part_of_a_command]

Nếu kết quả là như mong đợi. Đi với:

pkill -f [part_of_a_command]

hoặc sử dụng:pgrep -f "command name"
Magne

3

Thú vị không ai nhắc đến cái này. pidof xuất các pids phân tách không gian của các tiến trình khớp với tên tiến trình đã thông qua. Như vậy, bạn có thể trực tiếp sử dụng đầu ra của nó killmà không cần đường ống. Trên Arch Linux tôi sử dụng

kill -9 $(pidof <proc name>)

Nhược điểm của giải pháp này là nó không cho phép sử dụng các biểu thức thông thường.


0

Tôi sẽ đề nghị bạn thử pkill.

Ví dụ: ps -ef | pkill -f command

Để hiển thị danh sách tất cả các quy trình bị giết trước tiên, hãy thử pgrep:

Ví dụ: ps -ef | pgrep -f command


1
Mục đích của đường ống đầu ra ps -efvào pkillhoặc là pgrepgì? Các lệnh này không đọc từ đầu vào tiêu chuẩn.
Kusalananda

0

Bạn có thể giết nhiều tiến trình khác nhau bằng cách sử dụng lệnh bên dưới

pkill -9 -f "\.\/.+\s\.|process1|process2|process3\[^"

Lưu ý rằng điều này sẽ giết quá trình phù hợp với mô hình trên, có nghĩa là process1abc process2def process3ghicũng sẽ bị giết.


-1

pgrep "name-of-application" | xargs kill -9

Đã đủ đơn giản để nhớ và làm việc tốt cho tôi.



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.