Команда pgrep: поиск PID по имени, опция -f и отличия pidof и pkill

Тестовая средаСемейство RHELAlmaLinux 9.8procps-ng 3.3Учётная запись rootDebian 12 · procps-ng 4.0.2 обычная учётная запись

Чтобы найти номер (PID) работающего процесса по имени, учётной записи или командной строке, используется команда pgrep. На сервере AlmaLinux 9 мы скопировали программу sleep под другими именами, запустили три процесса и сравнили, какие процессы находит каждая опция. Поиск по имени вернул только эти три процесса, а поиск по всей командной строке с -f вернул ещё и timeout, который их запустил.

Вывод ниже получен под учётной записью root на сервере AlmaLinux 9.8 и под обычной учётной записью на сервере Debian 12. Искомые процессы — копии sleep с именами pgdemo-a и pgdemo-b, запущенные через timeout 300, чтобы они сами завершились через 5 минут. Номера процессов (PID) и имя учётной записи в Debian (user1) заменены примерами, а версия procps-ng на сервере AlmaLinux указана только до основной и дополнительной версии.

1️⃣ Основы использования команды pgrep

  • ↪️ Поиск PID по имени и код возврата

Если после pgrep написать часть имени, команда выведет номера процессов, в имени которых есть эти символы, по одному в строке. Поиск pgdemo вернул три номера: два pgdemo-a и один pgdemo-b.

pgrep pgdemo
2143
2152
2155

Когда имя написали до pgdemo-a, остались только два pgdemo-a.

pgrep pgdemo-a
2143
2152

Искомый текст читается как расширенное регулярное выражение, а без опций поиск идёт только по имени процесса.

Если подходящих процессов нет, pgrep завершается, ничего не выводя, поэтому результат проверяют по коду возврата. После поиска несуществующего имени pgdemo-zz команда [echo $?] вернула 1.

pgrep pgdemo-zz
echo $?
1

Запуск без единого условия выдал ошибку ниже и код возврата 2. Страница man описывает коды возврата так: 0 (найдено), 1 (не найдено), 2 (синтаксическая ошибка в командной строке) и 3 (фатальная ошибка, например нехватка памяти).

pgrep
pgrep: no matching criteria specified
Try `pgrep --help' for more information.
echo $?
2

Если вместо вывода использовать этот код возврата как условие, скрипт сможет проверить, работает ли процесс. Версию показывает [pgrep -V]. На сервере Debian 12 был procps-ng 4.0.2, на сервере AlmaLinux 9.8 — procps-ng 3.3.

pgrep -V
pgrep from procps-ng 4.0.2

2️⃣ Опция pgrep -f и вывод -l, -a

  • ↪️ Процессы, которые попадают в результат при поиске по всей командной строке

По одному номеру не понять, что это за процесс, поэтому с -l выводят ещё и имя, а с -a — всю командную строку.

pgrep -l pgdemo
2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-b
pgrep -a pgdemo
2143 ./pgdemo-a 300
2152 ./pgdemo-a 301
2155 ./pgdemo-b 300

Числа 300 и 301 в конце вывода -a — это аргументы в секундах, переданные sleep. По этим аргументам мы различили два одноимённых pgdemo-a.

С -f pgrep ищет не по имени, а по всей командной строке. Поиск pgdemo-a с -f увеличил число номеров с двух до четырёх.

pgrep -f pgdemo-a
2141
2143
2150
2152

С добавленной -a стало видно, что две новые строки — это процессы timeout, получившие pgdemo-a как аргумент. Их имя timeout, но в командной строке есть pgdemo-a, поэтому они подошли под условие -f.

pgrep -af pgdemo-a
2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301

Используя -f внутри скрипта, проверьте, не попадает ли в результат сам скрипт. pgrep никогда не включает в результат сам себя, но если в командной строке скрипта, который запустил pgrep, есть искомый текст, этот скрипт тоже попадёт в результат.

При поиске pgdemo-a скриптом chk.sh, который передаёт полученный текст как есть в [pgrep -af], в последней строке добавился сам скрипт: bash chk.sh pgdemo-a.

bash chk.sh pgdemo-a
2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301
2160 bash chk.sh pgdemo-a

Шаблон [p]gdemo-a, в котором первая буква взята в квадратные скобки, как регулярное выражение находит тот же текст, что и pgdemo-a, но в командной строке скрипта скобки записаны буквально, поэтому она больше не подходит. После передачи этого шаблона тому же скрипту строка скрипта пропала и осталось только четыре строки.

bash chk.sh '[p]gdemo-a'
2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301

3️⃣ Опции условий pgrep

  • ↪️ -u учётная запись, -x точное имя, -n и -o, -c количество

С -x pgrep находит только процессы, у которых совпадает всё имя, а не его часть. По pgdemo ничего не нашлось, а по pgdemo-a нашлось два.

pgrep -x pgdemo
pgrep -lx pgdemo-a
2143 pgdemo-a
2152 pgdemo-a

-u отбирает процессы по учётной записи, которая их запустила. Если указать несколько учётных записей через запятую, будут найдены все процессы, принадлежащие любой из них. Три процесса, запущенные от root, нашлись все с [-u root], а с [-u daemon] не нашлось ни одного.

pgrep -u root -l pgdemo
2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-b
pgrep -u daemon -l pgdemo
pgrep -u root,daemon -c pgdemo
3

Несуществующая учётная запись дала ошибку [invalid user name] и код возврата 2.

pgrep -u no-such-user9 pgdemo
pgrep: invalid user name: no-such-user9

На обычной учётной записи сервера Debian 12 теми же опциями тоже нашёлся единственный sleep, запущенный от этой учётной записи.

pgrep -u user1 -l sleep
3047 sleep
pgrep -u user1 -a sleep
3047 sleep 60

Если процессов с одинаковым именем несколько, -n выводит только самый недавно запущенный, а -o только самый ранний. Из двух pgdemo-a, запущенных с разницей в 2 секунды, -n выбрала более поздний, а -o более ранний.

pgrep -n pgdemo-a
2152
pgrep -o pgdemo-a
2143

Страница man указывает, что -n и -o нельзя использовать вместе. При указании обеих вывелась только справка по использованию, без сообщения об ошибке.

-c выводит количество вместо номеров. Если ничего не найдено, выводится 0, а код возврата был 1.

pgrep -c pgdemo
3
pgrep -c pgdemo-zz
0

Сводка опций pgrep приведена ниже.

ОпцияКопироватьОписание
-f--fullИскать по всей командной строке, а не по имени
-l--list-nameВыводить имя вместе с номером
-a--list-fullВыводить всю командную строку вместе с номером
-x--exactИскать только процессы с полностью совпадающим именем
-u--euidТолько процессы указанной учётной записи; при нескольких через запятую — любой из них
-n--newestСамый недавно запущенный из подходящих
-o--oldestСамый ранний из подходящих
-c--countВыводить количество вместо номеров; код возврата 1, если 0
-d--delimiterЗадать разделитель между номерами (по умолчанию перевод строки)
-V--versionВывести версию
ОпцияКопироватьОписание
-i--ignore-caseИскать без учёта регистра
-v--inverseНайти процессы, которые не подходят
-P--parentТолько дочерние процессы указанного номера родителя (PPID)
-t--terminalТолько процессы, привязанные к указанному терминалу
-g--pgroupТолько процессы указанного номера группы процессов
-s--sessionТолько процессы указанного номера сеанса
-U--uidТолько процессы с тем же реальным ID пользователя
-G--groupТолько процессы с тем же реальным ID группы
-w--lightweightВыводить все номера потоков вместо номеров процессов

🔲 Симулятор команды pgrep

Симулятор ниже начинается со списка из шести строк pgdemo и timeout и примеров процессов. Нажимайте на чипы, чтобы сравнить в списке слева строки, которые находит каждая опция, и посмотрите через [pgrep -l pgdemo], как сокращается результат после [pkill pgdemo-b].

Симулятор команды pgrepprocps-ng 3.3
[root@server work]#
Работает только в браузере. В списке слева значения для примера, а рядом со строками, найденными pgrep, появляется [Just matched]. [pkill] лишь имитирует, удаляя строки из списка.

4️⃣ Разница между pgrep, pidof и pkill

  • ↪️ pidof ищет точное имя, pkill отправляет сигнал

pidof без регулярных выражений находит только процессы, у которых полностью совпадает имя программы, и выводит номера в одну строку через пробел. Поиск pgdemo-a вывел оба номера в одной строке, первым был 2152, запущенный позже.

pidof pgdemo-a
2152 2143

По части имени pgdemo, в отличие от pgrep, pidof ничего не нашла, а код возврата был 1. Если нужен только один номер, добавьте -s. [pidof -s pgdemo-a] вывела только 2152.

pidof pgdemo
pidof -s pgdemo-a
2152

Чтобы увидеть время запуска и номер родителя (PPID) найденных номеров, соедините их запятыми через pgrep -d и передайте в опцию -p, которую понимает команда ps.

pgrep -d, pgdemo
2143,2152,2155
ps -fp $(pgrep -d, -x pgdemo-a)
UID          PID    PPID  C STIME TTY          TIME CMD
root        2143    2141  0 15:59 ?        00:00:00 ./pgdemo-a 300
root        2152    2150  0 15:59 ?        00:00:00 ./pgdemo-a 301

2141 и 2150 в столбце PPID — номера процессов timeout, которые запустили оба pgdemo-a.

pkill находит процессы по тем же условиям, что и pgrep, но вместо вывода номеров отправляет им сигнал. Если сигнал не указан, отправляется SIGTERM, а сменить его можно, как в [pkill -HUP имя].

pkill отправляет сигнал сразу, как только находит процесс, поэтому сначала проверьте цели через [pgrep -a] или [pgrep -af] с теми же условиями. При поиске с -f целью становятся и процессы timeout или скрипты, в командной строке которых есть тот же текст. Если номер уже известен, отправьте сигнал только ему с помощью команды kill.

КомандаКритерий поискаВыводНазначение
pgrepЧасть имени (regex), с -f вся командная строкаНомера; имя и командная строка с -l, -aТолько поиск
pidofПолное имя программыНомера в одной строкеТолько поиск
pkillТе же условия, что у pgrepНетСигнал найденным процессам (по умолчанию SIGTERM)

🔢 FAQ & рекомендуемые материалы

pgrep сравнивает имя процесса только до 15 символов, хранящихся в /proc/PID/stat. Если имя длиннее 15 символов, ищите по первым 15 символам или используйте -f для поиска по всей командной строке из /proc/PID/cmdline.

Если фильтровать список ps через grep, командная строка самого grep тоже содержит искомое имя, поэтому он может попасть в результат. pgrep никогда не включает в результат сам себя и выводит только номера, которые удобно передавать другим командам.

С -v pgrep инвертирует условие и находит процессы, которые не подходят. В pkill короткую опцию -v использовать нельзя, чтобы избежать ошибок.

ℹ️ О партнёрских ссылках
Материалы этого сайта содержат партнёрские ссылки. Если посетитель покупает товар или услугу по такой ссылке, сайт получает комиссию от продавца. При этом сумма, которую платит покупатель (при акционных скидках сумма снижается ↓), не увеличивается. Указанные цены, скидки и наличие актуальны на момент написания и могут отличаться, поэтому перед покупкой уточняйте их у продавца. Товары выбираются и оцениваются по нашим собственным критериям, а комиссия не влияет ни на порядок, ни на содержание обзоров.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Докажите, что вы человек: 6   +   3   =