Вам нужен способ найти свои процессы, которые выполнялись некоторое время. Для этого полезно знать, что параметр etime показывает время, прошедшее с начала процесса, в формате DD-чч: мм: сс, где каждая большая часть является необязательной. Итак, вы можете сделать
ps -U sauer -o etime,pid,command
(в AIX вы можете использовать ps -U sauer -o "%t,%p,%c"
)
Вы можете использовать -t $( tty)
вместо имени -U username
для выбора процессов в текущем tty (или в текущем терминале). Это то, что я сделаю позже. Также обратите внимание, что выполнение -o cmd=
подавляет заголовок столбца, но означает, что вам нужно несколько параметров -o.
Таким образом, вы получите команду ps -t $(tty) -o etime= -o pid= -o command=
чтобы показать все процессы, запущенные на текущем терминале, со столбцами "истекшее время настенных часов", "идентификатор процесса" и "команда" и подавление заголовков столбцов.
Теперь вам нужно получить только те, которые работали дольше, чем любые секунды. Итак, вам нужно извлечь первый столбец и преобразовать время в секунды. Как насчет сценария оболочки, чтобы сделать это (ksh/bash):
ps -t $(tty) -o etime= -o pid= -o command= | while read time pid cmd
do
secs=0
while true
do
part=${time##*:}
secs=$(( secs + ${part#0} ))
[[ "$part" != "$time" ]] || break # only had seconds
time=${time%:$part}
part=${time##*:}
secs=$(( secs + (60 * ${part#0}) ))
[[ "$part" != "$time" ]] || break # only had minutes left
time=${time%:$part}
part=${time##*-}
secs=$(( secs + (60 * 60 * ${part#0}) ))
[[ "$part" != "$time" ]] || break # only had hours left
time=${time%-$part} # all that's left are days-hours
secs=$(( secs + (24 * 60 * 60 * time) ))
break
done
echo "Process '$cmd' (pid '$pid') has been up for '$secs' seconds"
done
Пара вещей, возможно, потребуется объяснить. ${part#0}
находится там, так что времена, такие как "06" секунд, преобразуются в "6" вместо того, чтобы рассматриваться как восьмеричные. Конечно, восьмеричное 06 и десятичное 6 одинаковы, но восьмеричное 09 недопустимо, и снаряды иногда жалуются на это.
Другая вещь состоит в том, что ${var##*:}
оценивается как $ var с наибольшей строкой, совпадающей с "*:", обрезанной спереди (один #
- самое короткое совпадение, а %%
/ %
делает то же самое с конец). Если шаблон не совпадает, он оценивается в $var
. Таким образом, мы вытягиваем все, кроме секунд, добавляем это к секундам, а затем удаляем секунды с конца. Если у нас есть вещи, это минуты. Итак, восстановите минуты, переведите их в секунды, добавьте к промежуточному итогу, обрежьте его с конца. И так далее.
Хорошо. Оттуда, теперь вам просто нужно поставить #!/bin/ksh
(или bash, если нужно) вверху, и у вас есть скрипт. Кроме того, вам также нужен способ найти только те пиды, которые работают более X секунд. Как насчет файла в /tmp. Давайте использовать это вместо команды echo:
if [[ $secs -gt 120 ]]
then
{ cat /tmp/pids.$$; echo "$pid $cmd"; } 2>/dev/null | sort -u > /tmp/pids.$$.tmp
while read p c
do
if ps -p $p >/dev/null 2>&1
then
# put it back in the list
echo "$p $c" > /tmp/pids.$$
else
echo "Command '$c' exited" | mailx -s "exit report" $USER
fi
done < /tmp/pids.$$.tmp
fi
Теперь все, что вам нужно сделать, это обернуть всю гигантскую вещь внутри цикла
в то время как true делает # большой цикл while и оператор if 10 sleep
Назовите это process_monitor.sh
и вставьте process_monitor.sh&
в ваш .profile или .bash_login или что-то еще. Это будет происходить в фоновом режиме, наблюдая за всеми процессами в этом терминале, и когда он найдет один запущенный более 120 секунд, он добавит его в список, чтобы посмотреть, и отправит вам электронное письмо, когда процесс завершится.
Есть вещи, которые я, вероятно, добавлю, чтобы сделать его более красивым, например, захват сигнала EXIT, удаление временных файлов при выходе из скрипта и т.д. Но это упражнение для тебя. Надеюсь, этого должно быть достаточно, чтобы вы поправились. :)