मैं "t" से अधिक पुरानी प्रक्रियाओं को कैसे मार सकता हूँ?


14

पहला, हां मैंने यह प्रश्न देखा है:

पुरानी प्रक्रियाओं को खोजें (मारें)

वहां के उत्तर गलत हैं और काम नहीं करते हैं। मैंने उसी के अनुसार मतदान किया है और टिप्पणी की है।

जिन प्रक्रियाओं को मैं मारना चाहता हूं, वे इस तरह दिखती हैं, जैसे ps aux | grep page.py:

अपाचे 424 0.0 0.1 6996 4564? S 07:02 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 2686 0.0 0.1 7000 3460? S Sep10 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 2926 0.0 0.0 6996 1404? S Sep02 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 7398 0.0 0.0 6996 1400? S Sep01 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 9423 0.0 0.1 6996 3824? S Sep10 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 11022 0.0 0.0 7004 1400? S Sep01 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 15343 0.0 0.1 7004 3788? S Sep09 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 15364 0.0 0.1 7004 3792? S Sep09 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 15397 0.0 0.1 6996 3788? S Sep09 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 16817 0.0 0.1 7000 3788? S Sep09 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 17590 0.0 0.0 7000 1432? S Sep07 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 24448 0.0 0.0 7000 1432? S Sep07 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py
अपाचे 30361 0.0 0.1 6996 3776? S Sep09 0:00 /usr/bin/python2.6/u/apps/pysnpp/current/bin/page.py

मैं एक साधारण दैनिक क्रोन सेटअप करना चाहता हूं page.pyजो एक घंटे से अधिक पुरानी प्रक्रियाओं को ढूंढ और मार देगा ।

उपर्युक्त प्रश्न पर स्वीकृत उत्तर काम नहीं करता है, क्योंकि यह कई बार मेल नहीं खाता है, यह बस उन प्रक्रियाओं से मेल खाता है जो 7 दिन से 7 दिन 23 घंटे 59 मिनट और 59 सेकंड से चल रहे हैं। मैं उन प्रक्रियाओं को मारना नहीं चाहता जो 1-2 घंटे से चल रही हैं, बल्कि 1 घंटे से ज्यादा कुछ भी नहीं है ।

उपर्युक्त प्रश्न का अन्य उत्तर findकाम नहीं करता है, कम से कम जेंटू या सेंटोस 5.4 पर काम नहीं करता है, यह या तो एक चेतावनी देता है, या उक्त चेतावनी की सलाह का पालन करने पर कुछ भी नहीं लौटाता है।

जवाबों:


22

GNU किलॉल अपने प्रक्रियानाम का उपयोग करके किसी भी आयु से अधिक पुरानी प्रक्रियाओं को मार सकता है।

if [[ "$(uname)" = "Linux" ]];then killall --older-than 1h page.py;fi

1
यह विकल्प CentOS 6.6 पर उपलब्ध नहीं है। संस्करण: किल्लल्ल (PSmisc) 22.6।
अनाम

9

क्रिस्टोफर के जवाब की बदौलत मैं इसे निम्नलिखित के अनुरूप ढाल सका:

find /proc -maxdepth 1 -user apache -type d -mmin +60 -exec basename {} \; \
| xargs ps | grep page.py | awk '{ print $1 }' | sudo xargs kill

-mmin मुझे जो आदेश याद आ रहा था वह मिला।


3
निश्चित नहीं है कि -mmin किसी प्रक्रिया की आयु का पता लगाने के लिए उपयुक्त है या नहीं।
लैटिनसुद

यह / proc / निर्देशिका प्रकट नहीं होता है एक महान सौदा संशोधित हो, तो यह काम करने लगता है। यह कहा जा रहा है, मैं यह दावा करना नहीं चाहता कि यह असंभव है।
क्रिस्टोफर कारेल

मुझे नहीं लगता कि यह आपके प्रश्न का उत्तर देता है क्योंकि यह उत्तर बहुत संकीर्ण है और प्रश्न व्यापक है।
poige

और मैं और भी अधिक कहूंगा - यह बिल्कुल भी काम नहीं करता है: find /proc -maxdepth 1 -type d -name 1 -mmin +60 -ls- / sbin / init को दिनों के लिए अपटाइम काउंट के बावजूद सूचीबद्ध नहीं किया जा रहा है, घंटों को नहीं। ऐसा लगता है कि आप / संशोधन / dirs संशोधन समय पर भरोसा नहीं कर सकते।
12'12

3
/ खरीद में टाइमस्टैम्प इस पर निर्भर नहीं किया जा सकता है, दुर्भाग्य से। कम से कम कोई और नहीं।
dpk 21

8

पाते हैं हमेशा काम नहीं, हर प्रणाली उपलब्ध etimes नहीं है, और यह मेरी regex newb स्थिति हो सकती है, लेकिन मुझे नहीं लगता कि आपको इससे अधिक कुछ भी चाहिए:

ps -eo pid,etimes,comm,user,tty | awk '{if ($4 ~ /builder/ && $5 ~ /pts/ && $2>600) print $1}'
  • सभी प्रक्रियाओं को सूचीबद्ध करें और कॉलम प्रदान करें PID, ELAPSED (etimes = seconds), COMMAND, USER, TT (धन्यवाद @Aoffman)
  • awk के साथ PID को प्रिंट करें जहां 4 वें कॉलम ($ 4, USER) में टेक्स्ट 'बिल्डर' है, और 5th कॉलम ($ 5, TT) में टेक्स्ट 'pts' है और ELAPSED कॉलम का मूल्य 600 सेकंड (धन्यवाद) से अधिक है (धन्यवाद)

फिर आप पाइप को मार सकते हैं या जो भी आपकी आवश्यकता हो सकती है।


मुझे लगता है कि यह अधिक मजबूत समाधानों में से एक है, विशेष रूप से आपके उपयोग के संदर्भ में ps, लेकिन मैं grepएकल में कई गुना गुना करूंगा awk, और सुरक्षा के लिए पैटर्न को विशेष स्तंभों से मिलान करने के लिए प्रतिबंधित करता है (बाहर शासन करने के लिए जैसे एक कमांड नाम मिलान बिल्डर, आदि)
jmtd

यह ठीक है जब आपका समय गुंजाइश दिनों में है, लेकिन काम नहीं करेगा यदि आप घंटों, मिनट या सेकंड में बीते हुए समय का परीक्षण करना चाहते हैं।
वेलास्टिमिल ओवसिक्क

"etime" के बजाय "etimes" का उपयोग करें, यह बीता हुआ समय सेकंड में वापस कर देगा जो कि पार्स करने के लिए बहुत आसान है।
एहोफमैन

@jmtd और ahofmann: मैंने आपकी टिप्पणी के अनुसार अपडेट किया है। मुझे आशा है कि जैसा कि आपने इरादा किया है
eugenevd

5
# get elapsed time in seconds, filter our only those who >= 3600 sec
ps axh -O etimes  | awk '{if ($2 >= 3600) print $2}'

यदि आप चाहते हैं कि आप psPIDs की सूची के साथ भीतर देखने के लिए फ़ीड कर सकते हैं, उदाहरण के लिए:

ps h -O etimes 1 2 3

2
etimesकेवल नए के लिए काम करता हैps
Tino

4

मुझे लगता है कि आप अपनी आवश्यकताओं को पूरा करने के लिए उन पिछले उत्तरों में से कुछ को संशोधित कर सकते हैं। अर्थात्:

में फ़ाइल के लिए (खोजें। -maxdepth 1 -user processuser -type d -mmin +60)
  do -9 $ (basename $ FILE) को मार दें, मैं कभी भी खोज के निष्पादन के साथ काम करने के लिए बेसनेम नहीं पा सकता हूं। मुझे पता है अगर तुम जानते हो कैसे!
किया हुआ

या

ps -eo pid, etime, कॉम | awk '$ 2! ~ / ^..:..// && $ 3 ~ / पेज \ .py / {प्रिंट $ 1}' | मारना -9

मुझे लगता है कि दूसरा आपकी आवश्यकताओं के लिए सबसे उपयुक्त हो सकता है। खोज संस्करण उस उपयोगकर्ता द्वारा अन्य प्रक्रियाओं को


नुकीला कर देगा - क्रिस्‍टोफरेल कारेल


7
kill -9अंतिम उपाय के रूप में उपयोग न करें । का प्रयोग करें -SIGINTया -SIGTERM
अगली सूचना तक रोक दिया गया।

यह बीते समय के प्रारूप को परीक्षण मानदंड के रूप में उपयोग कर रहा है, इसके मूल्य पर नहीं। एक घंटे से कम होने पर प्रारूप psमें समय का उत्पादन होगा ^..:..$
वेलास्टिमिल ओवसिक्क

4
apt-get install psmisc

killall -o 1h $proc_name

क्या आप psmiscउपयोगिता के बारे में अधिक समझाने में मदद कर सकते हैं ? ओपी ने CentOS का उल्लेख किया; क्या यह RPM के रूप में उपलब्ध है?
कास्टाग्लिया

4

समस्या

सेकंड के लिए कमांड का रूपांतरण etime(बीता हुआ समय) कॉलम ps। समय प्रारूप इस प्रारूप में है [[dd-]hh:]mm:ss। नए संस्करणों में psएक etimesकॉलम होता है जो etimeसेकंड में मूल्य को आउटपुट करता है ।

समाधान: सरल कस्टम awk फ़ंक्शन

यह कस्टम awk फ़ंक्शन etimeकॉलम के सभी स्वरूपों (जैसे 03-12:30:59, 00:07आदि) का समर्थन करता है । बस इसे अपनी awk स्क्रिप्ट में पेस्ट करें, यह वन-लाइनर्स फ्रेंडली सॉल्यूशन है।

function sec(T){C=split(T,A,"[:-]"); return A[C>3?C-3:99]*86400 + A[C>2?C-2:99]*3600 + A[C>1?C-1:99]*60 + A[C>0?C-0:99]*1}
  • sec(T) T को सेकंड में कनवर्ट करता है
  • T[[dd-]hh:]mm:ssप्रारूप में समय विनिर्देश (उदाहरण के लिए etime)
  • Cफ़ील्ड्स की गिनती T(awk के NF वेरिएबल के बराबर)
  • Aखेतों की सरणी T(awk के $ चर के बराबर)
  • A[C>3?C-3:99]यह चौथे क्रम (यानी दिनों की संख्या) को उल्टे क्रम में संदर्भित करने का सुरक्षित तरीका है। यह दृष्टिकोण उपयोगी है क्योंकि दिन और घंटे वैकल्पिक हैं। यदि सरणी लंबे समय तक पर्याप्त नहीं है तो यह मानदेय A[99]होगा जो 0मूल्य प्राप्त करेगा । मुझे लगता 99है कि ज्यादातर उपयोग के मामलों के लिए पर्याप्त उच्च है।
  • पूर्णांक के रूप में सेकंड देता है

वास्तविक विश्व उदाहरण

soffice.binयदि यह प्रक्रिया 180 सेकंड से अधिक पुरानी है, तो यह बैश ऑन्लाइनर चालू उपयोगकर्ता के तहत चलने वाली प्रक्रिया को मार देगा ।

kill -9 $(ps cx -o command,etime,pid | awk '/^soffice.bin/ {if (sec($2)>180) {print $3}} function sec(T){C=split(T,A,"[:-]"); return A[C>3?C-3:99]*86400 + A[C>2?C-2:99]*3600 + A[C>1?C-1:99]*60 + A[C>0?C-0:99]*1}')

1
बहुत बेहतर है कि अन्य जवाब दें। यह भी बहु सहारा संभालती है।
डेनी वेनबर्ग

पूर्ण कमांड / आर्ग्स स्ट्रिंग पर grep करने में सक्षम होने के लिए 'ps' प्रारूप सूची के अंत में 'कमांड' या 'args' रखना बेहतर होगा। शुरुआत में इसे रखने से पीएस लंबे कमांड को काट देगा।
मैक्सिमम

1

lstartमें क्षेत्र psके लिए एक सुसंगत समय प्रारूप है जो हम करने के लिए फ़ीड कर सकते हैं देता है dateअवधि के बाद सेकंड में बदलने के लिए। तब हम वर्तमान समय की तुलना करते हैं।

#!/bin/bash
current_time=$(date +%s)
ps axo lstart=,pid=,cmd= |
    grep page.py |
    while read line
    do
        # 60 * 60 is one hour, multiply additional or different factors for other thresholds 
        if (( $(date -d "${line:0:25}" +%s) < current_time - 60 * 60 ))
        then
            echo $line | cut -d ' ' -f 6    # change echo to kill
        fi
    done

0

मैंने पिछले पोस्ट में आपके द्वारा दिए गए उत्तर को संशोधित किया

ps -eo pid,etime,comm | 
egrep '^ *[0-9]+ +([0-9]+-[^ ]*|[0-9]{2}:[0-9]{2}:[0-9]{2}) +/usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py' | 
awk '{print $1}' | 
xargs kill

नियमित अभिव्यक्ति 2 प्रकार के दूसरे तर्क की खोज करती है:

  • अंक और एक ऋण चिह्न के रूप में दिन।
  • Hours:minutes:seconds अभिव्यक्ति।

युवा प्रक्रियाओं को छोड़कर सब कुछ मेल खाना चाहिए जिनके पास फॉर्म होगा minutes:seconds


वैकल्पिक रूप से हम इसे करने की कोशिश कर सकते हैं जिस तरह से पीएस करता है। / Proc / uptime के पहले तर्क को / proc / * / stat के 22 वें तर्क से अलग करें।
लेटिसस्यूड

0

यह शायद ओवरकिल है, लेकिन मुझे इसे खत्म करने और यह परीक्षण करने के लिए पर्याप्त उत्सुक मिला कि यह काम करता है (मेरे सिस्टम पर एक अलग प्रक्रिया नाम पर, निश्चित रूप से)। आप की कैप्चरिंग को मार सकता है $userऔर $pidregexp, जो मैं केवल डीबगिंग के लिए जोड़ा आसान बनाने के लिए, और वापस बाहर फाड़ की तरह महसूस नहीं किया था। पर्ल 5.10 से नामांकित कैप्चर एक जोड़े को अधिक लाइनों से दाढ़ी देगा, लेकिन यह पुराने पर्ल्स पर काम करना चाहिए।

आपको प्रिंट को एक हत्या के साथ बदलने की आवश्यकता होगी, निश्चित रूप से, लेकिन मैं वास्तव में अपने सिस्टम पर कुछ भी मारने के बारे में नहीं था।

#!/usr/bin/perl -T
use strict; use warnings;

$ENV{"PATH"} = "/usr/bin:/bin";                                                       

my (undef,undef,$hour) = localtime(time);                                             
my $target = $hour - 2; # Flag process before this hour                               
my $grep = 'page.py';                                                   

my @proclist = `ps -ef | grep $grep`;                                                 
foreach my $proc (@proclist)                                                          
{                                                                                     
    $proc =~ /(\w+)\s+(\d+)\s+\d+\s+\d+\s+(.*?).*/;                   
    my $user = $1;                                                                    
    my $pid = $2;                                                                     
    my $stime = $3;                                                                   

    $stime =~ s/(\d+):(\d+)/$1/;                                                      

    # We're going to do a numeric compare against strings that                        
    # potentially compare things like 'Aug01' when the STIME is old                   
    # enough.  We don't care, and we want to catch those old pids, so                 
    # we just turn the warnings off inside this foreach.                              
    no warnings 'numeric';                                                            

    unless ($stime > $target)                                                         
    {                                                                                 
        print "$pid\n";                                                               
    }                                                                                 
}


0

मेरे पास एक सर्वर है जिसमें गलत तारीखें हैं / खरीद और काम नहीं करता है इसलिए मैंने यह स्क्रिप्ट लिखी है:

#!/bin/bash

MAX_DAYS=7  #set the max days you want here
MAX_TIME=$(( $(date +'%s') - $((60*60*24*$MAX_DAYS)) ))

function search_and_destroy()
{
        PATTERN=$1
        for p in $(ps ux|grep "$PATTERN"|grep -v grep| awk '{ print $2 }')
        do
            test $(( $MAX_TIME - $(date -d "`ps -p $p -o lstart=`" +'%s') )) -ge 0 && kill -9 $p
        done
}

search_and_destroy " command1 "
search_and_destroy " command2 "

0

प्रक्रिया प्रविष्टियों के समय का उपयोग करते हुए पायथन संस्करण /proc:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# kills processes older than HOURS_DELTA hours

import os, time

SIGNAL=15
HOURS_DELTA=1

pids = [int(pid) for pid in os.listdir('/proc') if pid.isdigit()]

for pid in pids:
    if os.stat(os.path.join('/proc', str(pid))).st_ctime < time.time() - HOURS_DELTA * 3600:
        try:
            os.kill(pid, SIGNAL)
        except:
            print "Couldn't kill process %d" % pid

0

मैं इस सरल स्क्रिप्ट का उपयोग करता हूं यह सेकंड में प्रक्रिया और उम्र के दो तर्कों का नाम लेता है।

#!/bin/bash
# first argument name of the process to check
# second argument maximum age in seconds
# i.e kill lighttpd after 5 minutes
#   script.sh lighttpd 300 
process=$1
maximum_runtime=$2
pid=`pgrep $process`
if [ $? -ne 0 ]
then
        exit 0
fi
process_start_time=`stat /proc/$pid/cmdline --printf '%X'`
current_time=`date +%s`
let diff=$current_time-$process_start_time

if [ $diff -gt $maximum_runtime ]
then
        kill -3 $pid
fi

0

यह काम करना चाहिए

killall --older-than 1h $proc_name


1
यह [पहले से मौजूद उत्तरों] को कैसे जोड़ता या सुधारता है?
प्रतिक्रियाएँ

2
@ संदर्भ: सभी निष्पक्षता में, मुझे उल्लेख करने वाले एक उत्तर की खोज करनी थी --older-than और इसे अनदेखा करना आसान है। अन्य उत्तरों की तुलना में, यह बहुत आसान है, और यह अब EL7 पर भी उपलब्ध है।
स्वेन

@ यह सिर्फ एक प्रक्रिया को मारने के लिए awk / sed आदि का उपयोग करके स्क्रिप्ट लिखने की तुलना में आसान बनाता है, मुझे लगता है यह बहुत सरल और साफ है
जाबिर अहमद

0

मैं दूसरे समाधान से संतुष्ट नहीं था, उनमें से अधिकांश बहुत गूढ़ हैं (मेरा बैश ज्ञान सीमित है) और इसलिए मैं उन्हें अनुकूलित नहीं कर सकता ...
मैंने अपना स्वयं का समाधान बनाया है, यह शायद सबसे अच्छा नहीं है लेकिन यह काम करता है यह पठनीय है

आप इस स्क्रिप्ट को एक फ़ाइल में सहेज सकते हैं और इसे निष्पादन योग्य बना सकते हैं (अंततः इसे क्रोन का उपयोग करके कॉल कर सकते हैं)

#!/bin/bash
## time in second that trigger the kill
LIMIT=10
## [] skip the grep from the process list
PROC_NAME="[m]y process name"
## etimes return the time in seconds
TIME_SEC=$(ps axo etimes,pid,command | grep "$PROC_NAME" | awk {'print$1'})
PID=$(ps axo etimes,pid,command | grep "$PROC_NAME" | awk {'print$2'})

if [ -n "$TIME_SEC" ] 
    then
    if (( $TIME_SEC > $LIMIT )); then
        kill $PID
    fi
fi

-2

72 = 3 दिन 48 = 2 दिन 24 = 1 दिन

a1=$(TZ=72 date +%d) ps -ef| cat filex.txt | sed '/[JFMASOND][aepuco][nbrylgptvc] '$a1'/!d' | awk '{ print $2 " " $5 " " $6 }' > file2.txt

यह काम करता हैं :)


1
यह अच्छी तरह से हो सकता है, लेकिन इसे पढ़ना और सीखना बहुत कठिन है। कुछ newlines और सामान के साथ reformatting पर विचार करें ... स्क्रिप्ट निर्देश के लिए एक-लाइनर्स से बेहतर हैं।
फाल्कन मोमेंट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.