लाइनक्स बैश स्क्रिप्ट में दिए गए उपयोगकर्ता द्वारा 5 मिनट से अधिक समय तक चलने वाली सभी प्रक्रियाओं को मारें


18

मुझे ऐसी प्रक्रियाओं को मारने की आवश्यकता है जो किसी दिए गए प्रक्रिया के लिए कम से कम 5 मिनट से चल रही हैं।

मुझे हर पांच मिनट में उस कमांड को चलाना होगा।

बहुत - बहुत धन्यवाद !

(सिस्टम Centos5 है)

linux  bash 

जवाबों:


17
kill -9 $(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print $2}}')

जहाँ "procname" एक प्रक्रिया नाम है और 300 समय सीमा है


महान ऑनलाइनर। मैंने इसे -9अपनी प्रक्रियाओं के लिए थोड़ा मित्रवत होने के बिना उपयोग किया है और grep -v defunct |इससे पहले awkकि आप procname <defunct>अपने आउटपुट में देख सकते हैं , जो कि awk कमांड को वैध पीआईडी ​​नहीं लौटाएगा। और यह मार कमांड को तोड़ देगा।
माइकल हर्टल

मैं कहूंगा कि $(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print "kill "$2}}')थोड़ा चिकना है लेकिन जवाब वैसे भी बहुत अच्छा है
येवगेन

@HiteHat एक ही चीज़ के लिए कैसे करेगा लेकिन एक प्रक्रिया के लिए कुछ ख़ास है?
पेटर वासिल्व

मेरे समय को बर्बाद करने वाली एक बात यह है कि: 'awk NOT' का उपयोग करना चाहिए
cn123h

6

शायद एक crontab में इस तरह से लंबे समय से चल रहे कमांड चला?

timeout -k 300 command

5

पिछले दोनों उत्तरों से लाभ लेते हुए, मार स्क्रिप्ट का मेरा संस्करण:

#!/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

यह UID, NAME द्वारा प्रक्रिया को फ़िल्टर करता है और यदि निष्पादन का समय सीमा से अधिक है - प्रक्रियाओं को मारता है और ईमेल को रिपोर्ट भेजता है। यदि आपको उस ईमेल की आवश्यकता नहीं है - आप अंतिम पंक्ति में टिप्पणी कर सकते हैं।


2

मुझे इस पृष्ठ पर समाधान मिला: http://www.directadmin.com/forum/showthread.php?t=26179

एक खाली फाइल बनाएं और इसे किललंगप्रोफैश कहें

इसे कॉपी करें:

#!/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;

इसे अपने क्रोनजोब में रोकें

15 * * * * * root /{directory}/./killongproc.sh

4
यह आमतौर पर ऐसा करने के लिए एक बुरा विचार है। आप वास्तव में किस समस्या को हल करने की कोशिश कर रहे हैं? इसके अलावा, आपको इसका उपयोग नहीं करना चाहिए kill -9क्योंकि यह प्रक्रियाओं को बाहर निकलने से पहले एक सुंदर सफाई करने का मौका नहीं देता है।
अगली सूचना तक रोक दिया गया।

1
यह उन प्रक्रियाओं को मारता है जो सीपीयू समय (उपयोगकर्ता + सिस्टम) की कुछ मात्रा का उपभोग करते हैं, न कि ऐसी प्रक्रियाएं जो वास्तविक समय की कुछ राशि के लिए चल रही हैं (जैसे 1 घंटे से पहले शुरू हुई)।
955 पर मार्की 555

2

यहां एक स्क्रिप्ट है जिसे आप संशोधित कर सकते हैं कि आप क्या चाहते हैं।

EDIT ने नीचे दी गई स्क्रिप्ट को जोड़ा

#!/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

मुझे इसे संशोधित करने के लिए कोई पर्याप्त ज्ञान नहीं है, इसीलिए मैं आपसे पूछ रहा हूँ

2
बहुत जटिल। प्रक्रिया शुरू होने के बाद से आप सीधे बीता हुआ सेकंड दिखाने etimesके psलिए कॉलम का उपयोग कर सकते हैं (प्रारंभ समय से इसे गणना करने की आवश्यकता नहीं है)।
Marki555

@ Marki555 हाँ यह सच है। हालाँकि, इसके संस्करणों के साथ सिस्टम psसमर्थन नहीं करता है etimes(केवल etime) तो यह एक बढ़िया विकल्प है। मैंने इसका उपयोग तब किया जब शीर्ष उत्तर ने मुझे एक त्रुटि दीps
माइक

0

मुझे एक समान कार्य को हल करना था, और इसके लिए एक स्क्रिप्ट की आवश्यकता नहीं है। निष्कासन (सिग्नल सिग्मेंट) के निष्पादन योग्य प्रक्रियाओं के लिए "THECOMMAND":

killall -u $USER --older-than 5m THECOMMAND

वर्तमान उपयोगकर्ता के लिए प्रतिबंध -u $USERकेवल अनावश्यक त्रुटि संदेशों से बचने के लिए आवश्यक है यदि अन्य उपयोगकर्ता भी "THECOMMAND" चलाते हैं। अपने स्वयं के उपयोगकर्ता crontab में आप निम्नलिखित दर्ज करेंगे:

*/5 * * * *     killall -u $USER --older-than 5m THECOMMAND

एक सिस्टम crontab (उपयोगकर्ता 'रूट') में आप निम्नलिखित जोड़ेंगे:

*/5 * * * *     killall --older-than 5m THECOMMAND

यदि आप (SIGKILL) को समाप्त करने (SIGTERM) के बजाय प्रक्रियाओं को मारना चाहते हैं, --signal SIGKILLतो मापदंडों में जोड़कर स्पष्ट रूप से SIGKILL संकेत भेजें । सिस्टम क्रॉस्टैब के लिए उदाहरण:

*/5 * * * *     killall --older-than 5m --signal SIGKILL THECOMMAND

-4

Httpd के लिए

ps eaxo pid, समय, कॉम | tail -n + 2 | grep 'httpd' | awk 'मूल ($ 0,9,1)> 0' | awk '{प्रिंट $ 1}'

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.