Tôi cần lệnh để tiêu diệt các tiến trình đã chạy từ ít nhất 5 phút cho một quy trình nhất định.
Tôi sẽ phải chạy lệnh đó cứ sau năm phút.
Cảm ơn rất nhiều !
(hệ thống là Centos5)
Tôi cần lệnh để tiêu diệt các tiến trình đã chạy từ ít nhất 5 phút cho một quy trình nhất định.
Tôi sẽ phải chạy lệnh đó cứ sau năm phút.
Cảm ơn rất nhiều !
(hệ thống là Centos5)
Câu trả lời:
kill -9 $(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print $2}}')
trong đó "Procname" là tên quy trình và 300 đang chạy ngưỡng thời gian
$(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print "kill "$2}}')
là một chút mịn màng hơn nhưng dù sao câu trả lời là tuyệt vời
Phiên bản kill script của tôi, nhận lợi ích từ cả hai câu trả lời trước:
#!/bin/bash
#Email to send report
MY_EMAIL="example@email.com"
#Process name to kill
NAME_KILL="php"
#UID to kill
UID_KILL=33.
#Time in seconds which the process is allowed to run
KILL_TIME=60
KILL_LIST=()
EMAIL_LIST=()
while read PROC_UID PROC_PID PROC_ETIMES PROC_ETIME PROC_COMM PROC_ARGS; do
if [ $PROC_UID -eq $UID_KILL -a "$PROC_COMM" == "$NAME_KILL" -a $PROC_ETIMES -gt $KILL_TIME ]; then
KILL_LIST+=("$PROC_PID");
MSG="Killing '$PROC_ARGS' which runs for $PROC_ETIME";
EMAIL_LIST+=("$MSG");
echo "$MSG";
fi
done < <(ps eaxo uid,pid,etimes,etime,comm,args | tail -n+2)
if [ ${#KILL_LIST[*]} -gt 0 ]; then
kill -9 ${KILL_LIST[@]}
printf '%s\n' "${EMAIL_LIST[@]}" | mail -s "Long running processes killed" $MY_EMAIL
fi
Nó lọc quy trình theo UID, NAME và nếu thời gian thực hiện vượt quá giới hạn - giết chết các quy trình và gửi báo cáo đến email. Nếu bạn không cần email đó - bạn chỉ có thể nhận xét dòng cuối cùng.
Tôi đã tìm thấy giải pháp trên trang này: http://www.directadmin.com/forum/showthread.php?t=26179
Tạo một tập tin trống và gọi nó là killlongproc.sh
#!/bin/bash
# This script will kill process which running more than X hours
# egrep: the selected process; grep: hours
PIDS="`ps eaxo bsdtime,pid,comm | egrep "spamd|exim|mysqld|httpd" | grep " 1:" | awk '{print $2}'`"
# Kill the process
echo "Killing spamd, exim, mysqld and httpd processes running more than one hour..."
for i in ${PIDS}; do { echo "Killing $i"; kill -9 $i; }; done;
Dừng lại trong cronjob của bạn
15 * * * * * root /{directory}/./killongproc.sh
kill -9
vì nó không tạo cơ hội để dọn dẹp duyên dáng trước khi thoát.
Có một kịch bản ở đây mà bạn có thể sửa đổi để làm những gì bạn muốn.
EDIT đã thêm đoạn script bên dưới
#!/bin/bash
#
#Put the UID to kill on the next line
UID_KILL=1001
#Put the time in seconds which the process is allowed to run below
KILL_TIME=300
KILL_LIST=`{
ps -eo uid,pid,lstart | tail -n+2 |
while read PROC_UID PROC_PID PROC_LSTART; do
SECONDS=$[$(date +%s) - $(date -d"$PROC_LSTART" +%s)]
if [ $PROC_UID -eq $UID_KILL -a $SECONDS -gt $KILL_TIME ]; then
echo -n "$PROC_PID "
fi
done
}`
if [[ -n $KILL_LIST ]]
then
kill $KILL_LIST
fi
etimes
của ps
để hiển thị trực tiếp các giây đã trôi qua kể từ khi bắt đầu quá trình (không cần tính toán từ thời gian bắt đầu).
ps
không hỗ trợ etimes
(chỉ etime
) thì đây là một sự thay thế tuyệt vời. Tôi chỉ sử dụng nó khi câu trả lời hàng đầu cho tôi một lỗi từps
Tôi đã phải giải quyết một nhiệm vụ tương tự, và nó không cần một kịch bản. Để kết thúc quá trình (tín hiệu SIGTERM) của "THECOMMAND" thực thi:
killall -u $USER --older-than 5m THECOMMAND
Hạn chế đối với người dùng hiện tại -u $USER
chỉ cần thiết để tránh các thông báo lỗi không cần thiết nếu người dùng khác cũng chạy "THECOMMAND". Trong crontab người dùng của riêng bạn, bạn sẽ nhập như sau:
*/5 * * * * killall -u $USER --older-than 5m THECOMMAND
Trong một crontab hệ thống (người dùng 'root'), bạn sẽ thêm vào như sau:
*/5 * * * * killall --older-than 5m THECOMMAND
Nếu bạn muốn tiêu diệt (SIGKILL) các quy trình thay vì chấm dứt (SIGTERM) chúng, hãy gửi rõ ràng tín hiệu SIGKILL bằng cách thêm --signal SIGKILL
vào các tham số. Ví dụ cho một crontab hệ thống:
*/5 * * * * killall --older-than 5m --signal SIGKILL THECOMMAND
Dành cho httpd
ps eaxo pid, thời gian, comm | đuôi -n + 2 | grep 'httpd' | awk 'đế ($ 0,9,1)> 0' | awk '{in $ 1}'
-9
phải là một chút thân thiện hơn với các quy trình của tôi và đã thêmgrep -v defunct |
trước đóawk
như những gì bạn có thể thấyprocname <defunct>
trong đầu ra của mình, điều này sẽ khiến lệnh awk không trả về một PID hợp lệ. Và điều này sẽ phá vỡ lệnh kill.