“T” den daha eski süreçleri nasıl öldürürüm?


14

İlk olarak, evet bu soruyu gördüm:

Eski işlemleri bulma (ve öldürme)

Oradaki cevaplar yanlış ve işe yaramıyor. Oy verdim ve ona göre yorum yaptım.

Öldürmek istediğim işlemler şu şekilde listelendiğinde şöyle görünür ps aux | grep page.py:

apache 424 0.0 0.1 6996 4564? S 07:02 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 2686 0.0 0.1 7000 3460? S Eyl10 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 2926 0,0 0,0 6996 1404? S Eyl02 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 7398 0.0 0.0 6996 1400? S Eyl01 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 9423 0.0 0.1 6996 3824? S Eyl10 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 11022 0,0 0,0 7004 1400? S Eyl01 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15343 0.0 0.1 7004 3788? S Eyl09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15364 0.0 0.1 7004 3792? S Eyl09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15397 0.0 0.1 6996 3788? S Eyl09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 16817 0,0 0,1 7000 3788? S Eyl09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 17590 0,0 0,0 7000 1432? S Eyl07 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 24448 0,0 0,0 7000 1432? S Eyl07 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 30361 0.0 0.1 6996 3776? S Eyl09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py

page.pyBir saatten daha eski süreçleri bulup öldürecek basit bir günlük cron kurmaya çalışıyorum .

Yukarıda bahsedilen soruya kabul edilen cevap, birkaç kez uyuşmadığından işe yaramaz, sadece 7 günden 7 güne 23 saat 59 dakika 59 saniye süren işlemlerle eşleşir. 1-2 saatten uzun süren süreçleri öldürmek istemiyorum, daha çok 1 saatten fazla bir şey öldürmek istiyorum .

Yukarıda belirtilen soruya verilen diğer cevap find, en azından Gentoo veya CentOS 5.4'te değil, işe yaramıyor, ya bir uyarı veriyor ya da söz konusu uyarının tavsiyesi takip edilirse hiçbir şey döndürmüyor.

Yanıtlar:


22

GNU Killall, işlem adlarını kullanarak belirli bir yaştan daha eski işlemleri öldürebilir.

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

1
Bu seçenek CentOS 6.6'da mevcut değildir. Sürüm: killall (PSmisc) 22.6.
Onnonymous

9

Christopher'ın cevabı sayesinde bunu aşağıdakilere uyarlayabildim:

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

-mmin eksik olduğum find komutuydu.


3
-Mmin'in bir işlemin yaşını algılamak için uygun olup olmadığından emin değilim.
LatinSuD

/ Proc / dizinleri büyük ölçüde değiştirilmiş gibi görünmüyor, bu yüzden bu işe yarıyor gibi görünüyor. Bununla birlikte, bunun imkansız olduğunu iddia etmek istemem.
Christopher Karel

Bu sorunun sorunuzu cevapladığını sanmıyorum çünkü bu cevap çok dar ve soru daha geniş.
poige

Ve daha fazlasını söyleyebilirim - hiç işe yaramıyor: find /proc -maxdepth 1 -type d -name 1 -mmin +60 -ls- / sbin / init saatlerce değil günlerce çalışma süresine rağmen listelenmiyor. Görünüşe göre / proc / 's dirs değiştirme zamanına güvenemezsiniz.
poige

3
/ Proc içindeki zaman damgaları maalesef buna bağlı olamaz. En azından artık değil.
dpk

8

find her zaman işe yaramaz, her sistemin etimleri yoktur ve benim regex newb statüsü olabilir, ama bundan daha fazlasına ihtiyacınız olduğunu düşünmüyorum:

ps -eo pid,etimes,comm,user,tty | awk '{if ($4 ~ /builder/ && $5 ~ /pts/ && $2>600) print $1}'
  • tüm işlemleri listeler ve PID, ELAPSED (etimes = saniye), COMMAND, USER, TT sütunlarını sağlar (thanks @ahoffman)
  • awk ile 4. sütunun (4 $, USER) metin 'oluşturucu' ve 5. sütunun (5 $, TT) 'pts' metni içerdiği ve ELAPSED sütununun değeri 600 saniyeden büyük olduğu PID'yi yazdırın (teşekkürler @amtd)

daha sonra öldürmek ya da ihtiyacınız ne olursa olsun onu borulandırabilirsiniz.


Bu, özellikle kullanımınız açısından daha sağlam çözümlerden biri olduğunu düşünüyorum ps, ancak çoklu greps'yi tekli olarak katlayabilirim awkve güvenlik için desen eşleşmelerini belirli sütunlarla sınırlar (örneğin bir komut adı eşleşmesini ekarte etmek için) builder, etc.)
jmtd

Zaman kapsamınız günlerdeyse bu iyidir, ancak geçen süreyi saat, dakika veya saniye olarak test etmek istiyorsanız çalışmaz.
Vlastimil Ovčáčík

"etime" yerine "etimes" kullanın, bu, geçen süreyi ayrıştırmak için daha kolay olan saniye cinsinden döndürür.
ahofmann

@jmtd & ahofmann: Yorumunuza göre güncelledim. Umarım bu istediğin gibi
eugenevd

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

İsterseniz psiçinde aramak için PID listesi ile besleyebilirsiniz , örneğin:

ps h -O etimes 1 2 3

2
etimessadece daha yeni işlerps
Tino

4

Önceki cevapların bazılarını ihtiyaçlarınıza göre değiştirebilirsiniz. Yani:

FILE in için (bul. -maksupde 1 -kullanıcı işlemcisi -tip d -mmin +60)
  kill -9 $ (basename $ FILE) # Find'ın exec ile çalışmak için asla basename alamıyorum. Nasıl olduğunu biliyorsanız bana bildirin!
tamam

Veya

ps -eo pid, etime, iletişim | awk '$ 2! ~ /^..:..$/ && $ 3 ~ / sayfa \ .py / {print $ 1}' | öldür -9

Sanırım ikincisi ihtiyaçlarınıza en uygun olabilir. Bulma sürümü, o kullanıcı tarafından diğer işlemleri nuking Rüzgar -


Christopher Karel


7
kill -9Son çare olarak kullanmayın . -SIGINTVeya tuşunu kullanın -SIGTERM.
sonraki duyuruya kadar duraklatıldı.

Bu, geçen zamanın biçimini, değerini değil, test ölçütü olarak kullanmaktadır. pszaman ^..:..$bir saatten az olduğunda biçim olarak çıktı verir.
Vlastimil Ovčáčík

4
apt-get install psmisc

killall -o 1h $proc_name

psmiscYardımcı program hakkında daha fazla açıklamaya yardımcı olabilir misiniz? OP CentOS'tan bahsetti; RPM olarak kullanılabilir mi?
Castaglia

4

Sorun

Komut etimesütununu pssaniyeye dönüştürme (geçen süre) . Zaman belirtimi bu biçimde [[dd-]hh:]mm:ss. Yeni sürümlerinde saniye cinsinden değer çıktısı veren psbir etimessütun vardır etime.

Çözüm: basit özel awk işlevi

Bu özel awk fonksiyonu tüm biçimlerini destekler etimesütununda (örneğin 03-12:30:59, 00:07vs.). Sadece awk betiğinize yapıştırın, tek katmanlı dostu bir çözümdür.

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'yi saniyeye çevirir
  • T[[dd-]hh:]mm:ssbiçiminde zaman belirtimi (ör. etime)
  • Calan sayısı T(awk'nin NF değişkenine eşdeğer)
  • Aiçindeki alan dizisi T(awk $ değişkenine eşdeğer)
  • A[C>3?C-3:99]bu dördüncü değere (gün sayısı) ters sırayla başvurmanın güvenli bir yoludur. Bu yaklaşım faydalıdır çünkü günler ve saatler isteğe bağlıdır. Dizi yeterince uzun değilse A[99], 0değer verecek dereference . Ben varsayalım 99çoğu kullanım durumları için yetecek kadar yüksektir.
  • saniye değerini tamsayı olarak döndürür

Gerçek dünya örneği

Bu bash oneliner soffice.bin, işlem 180 saniyeden eski olursa, geçerli kullanıcı altında çalışan işlemi öldürecektir .

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
Diğer cevaplar çok daha iyi. ayrıca çoklu procları da yönetir.
Denny Weinberg

Tam komut / args dizesini grep edebilmek için 'ps' biçim listesinin sonuna 'command' veya 'args' koymak daha iyi olur. Başına yerleştirmek ps'in daha uzun komutları kısaltmasına neden olur.
Maksym

1

lstartAlan psbiz besleyebilir tutarlı zaman biçimini veren dateDönemden beri saniyeye dönüştürmek için. Sonra bunu şimdiki zamanla karşılaştırıyoruz.

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

Önceki yayında size verdikleri yanıtı değiştirdim

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

Normal ifade 2 tür ikinci argüman arar:

  • Gün basamak ve eksi işareti şeklinde.
  • Hours:minutes:seconds ifadesi.

Bu, forma sahip olan genç süreçler dışındaki her şeyle eşleşmelidir minutes:seconds.


Alternatif olarak PS'nin yaptığı gibi bunu deneyebiliriz. / Proc / uptime ilk argümanını / proc / * / stat'ın 22. argümanından soyutlayın.
LatinSuD

0

Bu muhtemelen aşırıya kaçıyor, ancak bitirmek ve çalıştığını test etmek için yeterince merak ettim (tabii ki sistemimdeki farklı bir işlem adında). Yalnızca hata ayıklama için eklediğim ve geri çekilmek gibi hissetmediğim normal ifadenin yakalanmasını $userve $pidbasitleştirilmesini öldürebilirsiniz . 5.10 perl adlı yakalanan yakalar birkaç satır daha tıraş olur, ancak bu eski perls üzerinde çalışması gerekir.

Tabii ki baskıyı bir öldürme ile değiştirmeniz gerekecek, ama aslında kendi sistemimdeki hiçbir şeyi öldürmek üzereydim.

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

/ Proc yanlış tarihlere sahip bir sunucu var ve bu yüzden bu komut dosyası yazdı bulmak işe yaramaz:

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

Aşağıdaki işlem girişlerinin ctime değerini kullanan Python sürümü /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

Bu basit komut dosyası, işlem ve yaş saniye olarak iki bağımsız değişken adı alır kullanın.

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

bu çalışmalı

killall --older-than 1h $proc_name


1
Bu [mevcut cevapları] nasıl ekler veya geliştirir?
Reaces

2
@Reaces: Tüm adalette, bir cevaptan bahsetmek zorunda kaldım --older-than ve bunu gözden kaçırmak kolay. Diğer cevaplara kıyasla, bu çok daha kolay ve şimdi EL7'de de mevcut.
Sven

@Bu sadece bir işlemi öldürmek için awk / sed vb kullanarak komut dosyaları yazmaktan daha kolay hale getirir, bu sanırım çok daha basit ve temiz
Jabir Ahmed

0

Diğer çözümden memnun kalmadım, çoğu çok şifreli (bash bilgim biraz sınırlı) ve bu yüzden onları özelleştiremiyorum ...
Kendi çözümümü yarattım, Muhtemelen en iyisi değil ama işe yarıyor ve okunabilir

Bu komut dosyasını bir dosyaya kaydedip yürütülebilir hale getirebilirsiniz (sonunda cron kullanarak çağırın)

#!/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 gün 48 = 2 gün 24 = 1 gün

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

işe yarıyor :)


1
Bu iyi olabilir, ancak okumak ve öğrenmek oldukça zordur. Bazı yeni satırlarla ve diğer şeylerle yeniden biçimlendirmeyi düşünün ... komut dosyaları, eğitim için tek satırdan daha iyidir.
Falcon Momot
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.