pkill không thể giết tiến trình với tiến trình cha mẹ id 1


7

Tôi muốn giết các quá trình sau bằng cách sử dụng

pkill "run_tcp_sender.sh"

hoặc là

pkill -SIGKILL  "run_tcp_sender.sh"


    root     14320     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14323     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14325     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14327     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14328     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14330     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22

nhưng nó là vô dụng các quy trình vẫn còn đó với những gì sai với lệnh của tôi?

BTW: Tôi có thể sử dụng lệnh sau để đạt được những gì tôi muốn

kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')

1
Trạng thái nào là quá trình khi chúng không thể bị giết? Các quy trình "Trạng thái D" thường phải thoát ra khỏi trạng thái D (khi I / O của chúng kết thúc) trước khi chúng xem xét các tín hiệu của chúng và các quy trình trạng thái Z không thể bị giết bất kể là gì (thiếu cha mẹ gặt hái đứa trẻ hoặc quản trị viên khởi động lại máy). Tôi nghĩ rằng việc sử dụng một lệnh khác có thể chỉ là bạn làm một việc khác trong một thời gian và các quy trình thay đổi trạng thái đối với bạn.
Bratchley

2
Liệu pgrep "run_tcp_sender.sh"trả về danh sách các quy trình bạn muốn giết, hay nó chỉ trả về một danh sách trống vì tất cả các quy trình được liệt kê là bash run_tcp_sender.sh ...?
Jonathan Callen

Câu trả lời:


18

pkilltheo mặc định sẽ gửi SIGTERMtín hiệu đến các quá trình để dừng lại. Đây là danh sách các tín hiệu bạn có thể gửi một quy trình. Bạn có thể gửi chúng theo tên hoặc số thông thường:

$ kill -l
 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

Vì vậy, bạn đang gửi tín hiệu # 15. Nếu các quy trình không phản hồi tín hiệu này thì bạn có thể cần sử dụng tín hiệu # 9 , pkill -SIGKILL.

Từ trang người đàn ông của pkill :

-tín hiệu

  Defines the signal to send to each matched process.  Either the
  numeric  or  the symbolic signal name can be used.  (pkill only.)

Các vấn đề với pkill

OP đã đề cập rằng anh ta đã không thành công trong việc pkill -SIGKILL "run_tcp"đi làm. Ban đầu, chúng tôi nghĩ rằng vấn đề phải làm với pkillkhả năng tự sát trước khi nó kết thúc việc giết tất cả các quy trình "run_tcp".

Nhưng điều đó thật khó chấp nhận khi đưa ra một ghi chú chân trong pkilltrang người đàn ông:

Quá trình pgrep hoặc pkill đang chạy sẽ không bao giờ tự báo cáo là khớp.

Thêm vào đó, @Gilles đã để lại một bình luận về cơ bản nói điều tương tự, rằng pkillnó không tự sát. Sau đó anh ấy cho chúng tôi một manh mối khá lớn về những gì đang thực sự xảy ra.

Đây là một ví dụ minh họa những gì OP và bản thân tôi đã thiếu:

bước 1 - tạo kịch bản buồn ngủ.bash

#!/bin/bash

sleep 10000

Bước 2 - tải lên một số tác vụ ngủ giả

$ for i in `seq 1 5`;do bash sleepy.bash & done
[1] 12703
[2] 12704
[3] 12705
[4] 12706
[5] 12707

Bước 3 - kiểm tra các tác vụ đang chạy

$ ps -eaf|egrep "sleep 10000|sleepy"
saml     12703 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12704 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12705 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12706 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12707 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12708 12704  0 21:48 pts/16   00:00:00 sleep 10000
saml     12709 12707  0 21:48 pts/16   00:00:00 sleep 10000
saml     12710 12705  0 21:48 pts/16   00:00:00 sleep 10000
saml     12711 12703  0 21:48 pts/16   00:00:00 sleep 10000
saml     12712 12706  0 21:48 pts/16   00:00:00 sleep 10000

bước 4 - thử sử dụng pkill của tôi

$ pkill -SIGTERM sleepy.bash

bước 5 - chuyện gì đã xảy ra?

Thực hiện pslệnh từ phía trên, chúng tôi thấy rằng không có quá trình nào bị giết, giống như vấn đề OP. Chuyện gì đang xảy ra vậy?

Hóa ra đây là một vấn đề trong cách chúng tôi đang cố gắng sử dụng pkill. Lệnh:

pkill -SIGTERM "sleepy.bash"

đã tìm kiếm một quá trình với tên "buồn ngủ.bash" . Vâng, không có bất kỳ quá trình theo tên đó. Có những quy trình được đặt tên là "bash ngủy.bash" . Vì vậy, pkillđã tìm kiếm các quá trình để giết và không tìm thấy bất kỳ và sau đó thoát ra.

Vì vậy, nếu chúng ta điều chỉnh một chút pkillchúng ta đang sử dụng điều này:

$ pkill -SIGTERM -f "sleepy.bash"
[1]   Terminated              bash sleepy.bash
[2]   Terminated              bash sleepy.bash
[3]   Terminated              bash sleepy.bash
[4]-  Terminated              bash sleepy.bash
[5]+  Terminated              bash sleepy.bash

Bây giờ chúng tôi nhận được hiệu ứng mà chúng tôi đang tìm kiếm. Sự khác biệt là gì? Chúng tôi đã sử dụng các -fcông tắc để pkillmà làm cho pkillsử dụng toàn bộ đường dẫn dòng lệnh khi kết hợp so với chỉ tên quá trình.

từ trang người đàn ông pkill

-f      The pattern is normally only matched against the process name.  
        When  -f  is  set, the full command line is used.

Các phương thức thay thế

giết, ps

Phương pháp này khá dài dòng nhưng cũng thực hiện công việc:

kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')

pgrep w / pkill & killall

Bạn có thể sử dụng hoặc pgrepđể cung cấp danh sách các bộ vi xử lý pkillhoặc sử dụng killallthay thế.

Ví dụ

# pgrep solution
$ pgrep "run_tcp" | pkill -SIGKILL

# killall
killall -SIGKILL -r run_tcp

Người giới thiệu


Tại sao SIGTERM không hoạt động ở đây?
sương mù

Không chắc chắn, điều đó báo hiệu ứng dụng tự tắt, nhưng nó không phản hồi. SIGKILL, là hệ điều hành phá hủy quy trình, nó hơi nặng tay để sử dụng mọi lúc. Tốt hơn là để ứng dụng tự đóng nếu có thể.
slm

pkill -SIGKILL lại vô dụng! Tôi chỉ có thể sử dụng kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')để giết, lạ! bạn có biết tại sao? cảm ơn
Misteryes

Không, pkillkhông phải là tự giết mình, và không, đó không phải là vấn đề tín hiệu nào được gửi đi. Nó không gửi bất kỳ tín hiệu nào vì không có quá trình theo tên đó.
Gilles 'SO- ngừng trở nên xấu xa'


5

Điều này không liên quan đến ID tiến trình cha. Vấn đề đơn giản là bạn đang giết tất cả các quy trình đang chạy run_tcp_sender.sh, nhưng bạn không có các quy trình đó - các quy trình bạn quan tâm đang chạy bash.

Bạn có thể hướng dẫn pkillđể khớp trên toàn bộ dòng lệnh:

pkill -f '^bash run_tcp_sender.sh'

Một cách tiếp cận khác là giết tất cả các tiến trình có kịch bản mở. Điều đó có thể gây thiệt hại tài sản thế chấp, ví dụ như một biên tập viên chỉ đang mở tập lệnh.

fuser -k /path/to/run_tcp_sender.sh

Miễn là bạn không chỉnh sửa tập lệnh thành root, chỉ giết các tiến trình của root sẽ giải quyết vấn đề đó:

kill $(lsof -uroot /path/to/run_tcp_sender.sh)

0

Cố gắng giết quá trình với "tín hiệu 9", ý tôi là sử dụng

kill -9 PID

thông thường tín hiệu 9 không được khuyến nghị để giết chết cơ sở dữ liệu

nếu quá trình vẫn còn trong bộ nhớ, một số i / o bị mất hoặc quá trình đang chờ hoàn thành

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.