Як перевірити, як довго працює процес?


242

Я хотів би цього не робити, запускаючи процес із програми моніторингу.

Відповіді:


311

У Linux з psвід procps(-ng)(і більшості інших систем , так як це визначається POSIX):

ps -o etime= -p "$$" 

Де $$знаходиться PID процесу, який ви хочете перевірити. Це поверне минулий час у форматі [[dd-]hh:]mm:ss.

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

Або з новішими версіями набору інструментів propps-ng (3.3.0 або вище) в Linux або на FreeBSD 9.0 або вище (і, можливо, інших) використовуйте:

ps -o etimes= -p "$$"

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

В Linux psпрограма отримує це звідки /proc/$$/stat, де одним із полів (див. man proc) Є час початку процесу. Це, на жаль, вказано як час у джиффах (довільний лічильник часу, що використовується в ядрі Linux) з моменту завантаження системи. Отже, ви повинні визначити час, коли система завантажилася (з /proc/stat), кількість джифтів за секунду в цій системі, а потім зробити математику, щоб отримати пройдений час у корисному форматі.

Це виявляється смішно складним для знаходження значення HZ (тобто джифтів за секунду). З коментарів, що sysinfo.cвходять до пакету propps, можна А) включити файл заголовка ядра та перекомпілювати, якщо використовується інше ядро; В) використовувати функцію posix sysconf(), яка, на жаль, використовує жорстко закодоване значення, зібране в бібліотеку С, або 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на сторінках man.
Кент Павар

16
@KentPawar Це не помилка друку. Порожня =придушує заголовок. Спробуйте без цього або спробуйтеps -p $$ -o etime="Silly Header Here"
mattdm

4
ps -p $ (pgrep find) -o etime =
mafrosis

1
Приємно. Я віддаю перевагу etimesсобі, оскільки тоді це читається машиною
Asfand Qazi

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

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


3
Знайти значення HZ (тобто джиффі в секунду) виявляється смішно складним! З коментарів у sysinfo.cпакеті propps можна а) включити файл заголовка ядра (і перекомпілювати, якщо використовується інше ядро, б) використовувати функцію 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-] hh:] mm: ss.

Таким чином, ви можете запустити це, щоб отримати PID та минулий час кожного процесу:

$ ps -eo pid,etime

Якщо ви хочете, щоб минув час певного PID (наприклад, 12345), ви можете зробити щось на кшталт:

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

( Редагувати : виявляється, що для вищевказаної команди є коротший синтаксис; див . Відповідь mattdm )


5

Не впевнені, чому це ще не запропоновано: в Linux ви можете stat()/ / / / nnn] каталог для вашого PID.

Така поведінка явно призначена для повернення часу запуску процесу, який він може робити при високій роздільній здатності, і який ядро ​​може робити точно, не маючи хакі, оскільки ядро ​​може (очевидно) просто перевірити відповідну інформацію. Поля доступу, зміни даних та зміни статусу повертають час початку процесу.

Найкраще, що ви можете використовувати stat(1)в оболонці або відповідне прив'язування до stat(2)$ favorite_programming_language, тож вам навіть не знадобиться запускати зовнішній процес.

Зверніть увагу, що це не працює з /usr/compat/linux/procFreeBSD; повернені часи доступу / модифікації / зміни статусу - це поточний час, а час народження - епоха UNIX. Дуже дурна підтримка не існує, якщо ви запитаєте мене.


Де у висновку stat я бачу інформацію? Я бачу лише доступ, зміну та зміну.
thepang

@Tshepang Зверніть увагу, що ці значення однакові, і це час початку процесу. Ви все ще повинні зайнятись математикою, але це, безумовно, краще, ніж намагатися розгадати джиффі, як зазначено у моїй відповіді.
mattdm

Ви називаєте це так: stat /proc/4480це дасть вам дати народження, зміни, зміни та доступу до процесу. Якщо вам потрібен ідентифікатор процесу, просто використовуйте "top"
user890332

2

Якщо ви можете запустити час, а потім виконати команду, ви отримаєте саме те, що шукаєте. Це неможливо зробити проти вже запущеної команди.

[0]% часу сну 20

сон 20 0,00s користувач 0,00s система 0% процесор 20.014 всього


Чи знаєте ви, як я можу це зробити під час моніторингу запущеного процесу, поки він не закінчиться?
lrkwz

1

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

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

де 13494ваш процес процесу


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 може бути проблематичним, воно перекошує
slm

1

Час минув у секундах: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)


Мені здається, це дуже незначна зміна тієї, про яку вже згадувався mattdm : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller

Цей не працював для мене на моєму дуже мінімальному екземплярі альпійського докера, тому я написав цей
Shardj
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.