Как проверить, как долго запущен процесс?


243

Я хотел бы избежать этого, запустив процесс из приложения мониторинга.

Ответы:


311

В Linux с psfrom procps(-ng)(и в большинстве других систем, так как это указано в POSIX):

ps -o etime= -p "$$" 

Где $$находится PID процесса, который вы хотите проверить. Это вернет истекшее время в формате [[dd-]hh:]mm:ss.

Использование -o etimeговорит, psчто вы просто хотите, чтобы поле истекшего времени, и =в конце этого подавляет заголовок (без, вы получите строку, которая говорит, ELAPSEDа затем время на следующей строке; с, вы получите только одну строку со временем) ,

Или, с более новыми версиями набора инструментов procps-ng (3.3.0 или выше) в Linux или во FreeBSD 9.0 или выше (и, возможно, в других), используйте:

ps -o etimes= -p "$$"

(с добавлением s) для форматирования времени в секундах, что более полезно в сценариях.

В Linux psпрограмма получает это /proc/$$/stat, откуда одно из полей (см. man proc) - время запуска процесса. К сожалению, это указывается как время в jiffies (произвольный счетчик времени, используемый в ядре Linux) с момента загрузки системы. Таким образом, вы должны определить время загрузки системы (с /proc/stat), количество jiffies в секунду в этой системе, а затем выполнить математические расчеты, чтобы получить истекшее время в полезном формате.

Оказывается, нелепо сложно найти значение HZ (т. Е. Джиффы в секунду). Из комментариев sysinfo.cв пакете procps можно A) включить файл заголовка ядра и перекомпилировать, если используется другое ядро, B) использовать sysconf()функцию posix , которая, к сожалению, использует жестко запрограммированное значение, скомпилированное в библиотеку C, или C) спросить ядро, но официального интерфейса для этого нет. Итак, psкод включает в себя ряд кладжей, по которым он определяет правильное значение. Ух ты.

Так что удобно, psчто все это сделает за вас. :)

Как отмечает пользователь @ 336_, в Linux (это не переносимо) вы можете использовать statкоманду, чтобы просмотреть даты доступа, изменения или изменения статуса для каталога /proc/$$(где снова $$интересующий процесс). Все три числа должны быть одинаковыми, поэтому

stat -c%X /proc/$$

даст вам время $$начала процесса , в секундах с начала эпохи. Это все еще не совсем то, что вы хотите, так как вам все еще нужно сделать математику, чтобы вычесть это из текущего времени, чтобы получить истекшее время - я думаю, что-то вроде date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"бы сработало, но это немного неуклюже. Одним из возможных преимуществ является то, что если вы используете вывод в длинном формате, например, -c%xвместо -c%X, вы получите большее разрешение, чем целое число секунд. Но, если вам это нужно, вы, вероятно, должны использовать подход аудита процессов, потому что время выполнения команды stat будет влиять на точность.


1
Здравствуй! Это etime=опечатка? Я могу найти только etimeв справочных страницах.
Кент Павар

16
@KentPawar Это не опечатка. Пустой =подавляет заголовок. Попробуйте это без, или попробуйтеps -p $$ -o etime="Silly Header Here"
mattdm

4
ps -p $ (pgrep find) -o etime =
мафроз

1
Приятно. Я предпочитаю etimesсебя, так как тогда она машиночитаема
Асфанд Кази

1
@alexmurray Это просто вызывает sysconf()и, следовательно, дает жестко запрограммированное значение из библиотеки C, как уже было сказано, не так ли?
mattdm

36

Портативный:

% ps -o stime,time $$
STIME     TIME
Jan30 00:00:06

т.е. эта оболочка была запущена 30 января и заняла около 6 секунд процессорного времени.

Могут быть более точные или более понятные, но менее портативные способы получения этой информации. Проверьте документацию вашей psкоманды или вашей procфайловой системы.

Под Linux эта информация живет в /proc/$pid/stat.

awk '{print "CPU time: " $14+$15; print "start time: " $22}' /proc/$$/stat

Процессорное время находится в замешательстве; Я не знаю, как случайно найти значение jiffy из оболочки. Время запуска относительно времени загрузки (находится в /proc/uptime).


3
Найти значение HZ (т. Е. Jiffies in second) оказывается нелепо сложно! Из комментариев в sysinfo.cпакете procps можно: а) включить файл заголовка ядра (и перекомпилировать, если используется другое ядро, б) использовать функцию posix sysconf (), которая, к сожалению, использует жестко запрограммированное значение, скомпилированное в библиотека c или c) запросить ядро, и для этого нет официального интерфейса. Итак, код включает в себя ряд кладжей, по которым он определяет правильное значение. Ух ты.
Mattdm

1
На psстранице руководства указано, что timeэто «совокупное время процессора». Я думаю, что ищет ОП etime, или «истекшее время с начала процесса». pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo

1
В конце концов, это не так «переносимо»: «ps: stime: ключевое слово не найдено» во FreeBSD. Это, по крайней мере, поддерживает etime, хотя.
n.st

18
ps -eo pid,comm,cmd,start,etime | grep -i X

X это название процесса


2
вероятно, следует добавить grep -v grep.
Брайан

ps -o pid,comm,cmd,start,etime -p Xпосмотреть на PID X.
codeforester

13

psпринимает -oпараметр, чтобы указать формат вывода, и один из доступных столбцов etime. Согласно справочной странице:

etime - время, прошедшее с начала процесса, в формате [[dd-] чч:] мм: сс.

Таким образом, вы можете запустить это, чтобы получить PID и истекшее время каждого процесса:

$ ps -eo pid,etime

Если вы хотите, чтобы истекшее время определенного PID (например, 12345), вы можете сделать что-то вроде:

$ ps -eo pid,etime | awk '/^12345/ {print $2}'

( Edit : оказывается, есть более короткий синтаксис для вышеуказанной команды; см . Ответ mattdm )


5

Не знаете, почему это еще не было предложено: в Linux вы можете stat()использовать каталог / proc / [nnn] для вашего PID.

Это поведение явно предназначено для возврата времени запуска процесса, которое оно может выполнять с высоким разрешением и которое ядро ​​может делать точно без хаков jiffies, поскольку ядро ​​может (очевидно) просто проверять соответствующую информацию. Поля доступа, изменения данных и изменения состояния возвращают время начала процесса.

Лучше всего то, что вы можете использовать stat(1)в оболочке или соответствующую привязку stat(2)из $ favourite_programming_language, так что вам может даже не понадобиться запускать внешний процесс.

Обратите внимание, что это не работает с /usr/compat/linux/procFreeBSD; время доступа / изменения / изменения состояния - это текущее время, а время рождения - эпоха UNIX. Довольно глупо, что поддержки нет, если вы спросите меня.


Где в выводе stat я вижу информацию? Я вижу только доступ, изменение и изменение.
Чепанг

@Tshepang Обратите внимание, что все эти значения одинаковы, и они являются временем начала процесса. Вы все еще должны сделать математику, но это определенно лучше, чем пытаться выяснить смешные моменты, как отмечено в моем ответе.
Mattdm

Вы называете это так: stat /proc/4480это даст вам даты рождения, изменения, изменения и доступа к процессу. Если вам нужен идентификатор процесса, просто используйте "top"
user890332

2

Если вы можете запустить время и затем выполнить команду, вы получите именно то, что вы ищете. Вы не можете сделать это против уже запущенной команды.

[0]% времени сна 20

сон 20 0.00s пользователь 0.00s система 0% процессор 20.014 всего


Знаете ли вы, как я могу сделать это при мониторинге запущенного процесса, пока он не закончится?
lrkwz

1

Вы можете получить время начала процесса, посмотрев на statфайл статистики, сгенерированный им proc, отформатировав его dateи вычтя из текущего времени:

echo $(( $(date +%s) - $(date -d "$(stat /proc/13494/stat | grep Modify | sed 's/Modify: //')" +%s) ))

где 13494ваш процесс PID


1

$ ps -eo lstart получить время начала

$ ps -eo etime получить длительность / истекшее время

$ ps -eo pid,lstart,etime | grep 61819
  PID                   STARTED     ELAPSED
  61819 Mon Sep 17 03:01:35 2018    07:52:15

61819 - это идентификатор процесса.


Использование lstart может быть проблематичным, это перекосы - unix.stackexchange.com/questions/274610/...
ОДС

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.