Як я вбиваю процеси, старіші за "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 вересень 10:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 2926 0,0 0,0 6996 1404? S вересень 02:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 7398 0,0 0,0 6996 1400? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
апач 9423 0,0 0,1 6996 3824? S вересень 10:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 11022 0,0 0,0 7004 1400? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15343 0,0 0,1 7004 3788? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15364 0,0 0,1 7004 3792? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15397 0,0 0,1 6996 3788? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
апач 16817 0,0 0,1 7000 3788? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
апач 17590 0,0 0,0 7000 1432? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
апач 24448 0,0 0,0 7 000 1432? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 30361 0,0 0,1 6996 3776? S вересень 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py

Я хочу налаштувати простий щоденний крон, який знайде та вб'є будь-які page.pyпроцеси, старші години.

Прийнята відповідь на вищезазначене питання не працює, оскільки не відповідає діапазону разів, вона просто відповідає процесам, що тривали від 7 днів до 7 днів 23 години 59 хвилин і 59 секунд. Я не хочу вбивати процеси, що тривають від 1-2 годин, а навпаки, що перевищує 1 годину.

Інша відповідь на вищезазначене запитання з використанням findне працює, принаймні, не на Gentoo або CentOS 5.4, вона або виписує попередження, або нічого не повертає, якщо дотримуватися рекомендації зазначеного попередження.

Відповіді:


22

GNU Killall може вбивати процеси, старші за певний вік, використовуючи їх ім'я процесу.

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

1
Ця опція недоступна для CentOS 6.6. Версія: killall (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 підходить для визначення віку процесу.
LatinSuD

Здається, що / proc / каталоги не сильно змінюються, тому, здається, це працює. Попри це, я не хотів би стверджувати, що це неможливо.
Крістофер Карел

Я не думаю, що це відповідає на ваше запитання, оскільки ця відповідь занадто вузька і питання ширше.
poige

І я б сказав ще більше - він взагалі не працює: find /proc -maxdepth 1 -type d -name 1 -mmin +60 -ls- / sbin / init не відображається в списку, незважаючи на кількість робочих днів, а не годин. Здається, ви не можете покластися на час модифікації / proc / 'dirs модифікації.
poige

3
На жаль, від цього не можуть залежати часові позначки / proc. Принаймні, не більше.
dpk

8

Знайти не завжди працює, не кожна система має etimes, і це може бути мій статус newge newge, але я не думаю, що вам потрібно нічого більше, ніж це:

ps -eo pid,etimes,comm,user,tty | awk '{if ($4 ~ /builder/ && $5 ~ /pts/ && $2>600) print $1}'
  • перерахуйте всі процеси та надайте стовпці PID, ELAPSED (etimes = секунди), COMMAND, USER, TT (спасибі @ahoffman)
  • з awk надрукуйте PID, де 4-й стовпець ($ 4, USER) містить текст "builder", а 5-й стовпець ($ 5, TT) містить текст "pts", а стовпець ELAPSED має значення більше 600 с (спасибі @amtd)

то ви можете трубити це вбивство або все, що вам потрібно.


Я думаю, що це одне з більш надійних рішень, особливо з точки зору вашого використання ps, але я би склав декілька greps в єдиний awk, а для безпеки обмежте відповідність шаблону в конкретних стовпцях (щоб виключити, наприклад, відповідність імені команди будівельник тощо)
jmtd

Це добре, коли ваш часовий діапазон в днях, але не вийде, якщо ви хочете перевірити минулий час у годинах, хвилинах чи секундах.
Властиміл Овчачик

використовувати "etimes" замість "etime", це поверне минулий час у секундах, що набагато простіше проаналізувати.
ahofmann

@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}'

Якщо ви хочете, ви можете подати psсписок PID-адрес для пошуку, наприклад:

ps h -O etimes 1 2 3

2
etimesпрацює лише для новішихps
Тіно

4

Я думаю, ви можете змінити деякі з цих попередніх відповідей, щоб відповідати вашим потребам. А саме:

для FILE в (знайдіть -maxdepth 1 -користувач процесора -тип d -mmin +60)
  do kill -9 $ (basename $ FILE) # Я ніколи не можу отримати базове ім'я для роботи з findexec. Дайте мені знати, якщо ви вмієте!
зроблено

Або

ps -eo pid, etime, comm | awk '$ 2! ~ /^..:..$/ && $ 3 ~ / page \ .py / {print $ 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(еквівалентна NF змінної awk)
  • Aмасив полів у T(еквівалентний змінній $ awk)
  • A[C>3?C-3:99]це безпечний спосіб посилання на четверте значення (тобто кількість днів) у зворотному порядку. Цей підхід корисний, оскільки дні та години необов’язкові. Якщо масив недостатньо довгий, то його відновлення A[99]призведе до 0значення. Я припускаю 99, що досить висока для більшості випадків використання.
  • повертає секунди як ціле число

Приклад реального світу

Цей bash oneliner знищить 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
МНОГО краще, ніж відповідають інші. він також обробляє кілька проектів.
Денні Вайнберг

Було б краще розмістити "команду" або "аргументи" в кінці списку форматів "ps", щоб мати змогу перейти на повний рядок команд / args. Якщо розмістити його на початку, це призведе до обрізання ps довшими командами.
Максим

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.


Крім того, ми могли б спробувати зробити так, як це робить PS. Вилучіть перший аргумент / proc / uptime з 22-го аргументу / proc / * / stat.
LatinSuD

0

Це, мабуть, надмірно, але мені стало досить цікаво, щоб закінчити це і перевірити, чи він працює (звичайно, на іншу назву процесу в моїй системі, звичайно). Ви можете вбити захоплення $userта $pidспростити повторне вирівнювання, яке я додав лише для налагодження, і не відчуваю, як вирвати назад. Названі знімки з Perl 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

У мене є сервер з неправильними датами в / proc і пошук не працює, тому я написав цей сценарій:

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

Версія Python з використанням ctime записів процесу у /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
@Reaces: Чесно кажучи, мені довелося шукати одну відповідь, згадуючи, --older-than і це легко не помітити. Порівняно з іншими відповідями, це набагато простіше, і він доступний і зараз на EL7.
Свен

@ Зрозуміло, це просто простіше, ніж писати сценарії, використовуючи awk / sed тощо, щоб вбити процес, це, напевно, набагато простіше і чистіше
Джабір Ахмед

0

Я не був задоволений іншим рішенням, більшість із них занадто криптовалютні (мої баш-знання є обмеженими), і тому я не можу їх налаштувати ...
Я створив власне рішення, це, мабуть, не найкраще, але воно працює і воно читабельне

Ви можете зберегти цей скрипт у файлі та зробити його виконуваним (зрештою назвати його за допомогою cron)

#!/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
Це може бути, але читати та вчитися з цього досить важко. Подумайте про переформатування за допомогою нових рядків та інших матеріалів ... сценарії кращі за однокласні інструкції.
Falcon Momot
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.