← Весь справочник

pgrep и pkill

Найти процессы по имени или командной строке и отправить им сигнал без ps | grep

pgrep ищет процессы по шаблону и печатает их PID. pkill принимает те же условия, но вместо печати отправляет найденным процессам сигнал (по умолчанию TERM). Обе команды заменяют связку ps aux | grep … | awk … | xargs kill и не находят сами себя.

Синтаксис

pgrep [опции] шаблон
pkill [-сигнал] [опции] шаблон

Шаблон — расширенное регулярное выражение (ERE), и по умолчанию он ищется как подстрока в имени процесса (comm, до 15 символов). С -f — во всей командной строке.

Код возврата: 0 — что-то найдено, 1 — ничего, 2 — ошибка в опциях.

Как сопоставлять

ОпцияЧто делает
(без опций)шаблон ищется в имени процесса: pgrep ssh найдёт и sshd, и ssh-agent
-xимя должно совпасть целиком: pgrep -x sshd
-fискать в полной командной строке (с аргументами и путями)
-iбез учёта регистра
-vинвертировать: все процессы, которые не подходят

Фильтры

ОпцияЧто выбирает
-u пользовательпо эффективному пользователю (имя или UID, через запятую)
-U пользовательпо реальному пользователю
-G группапо реальной группе
-P PPIDтолько дети указанного процесса
-g PGID / -s SIDпо группе процессов / сессии
-t pts/0по терминалу
-r S,Dпо состоянию (R, S, D, Z, T — как в ps)
-n / -oтолько самый новый / самый старый из найденных
-O сектолько процессы старше указанного числа секунд
-F файлвзять PID из PID-файла
-Aисключить своих предков (оболочку, из которой запущен pgrep)

Вывод pgrep

ОпцияЧто печатает
(без опций)PID по одному на строку
-lPID и имя
-aPID и полную командную строку
-cтолько количество
-d ,разделитель вместо перевода строки: 12,34,56
-wидентификаторы потоков (TID) вместо PID

Опции pkill

ОпцияЧто делает
-HUP, -9, --signal TERMкакой сигнал отправить
-eпечатать каждый процесс, которому отправлен сигнал: … killed (pid 42)
-cнапечатать, скольким процессам отправлен сигнал
все фильтры pgrep-f, -x, -u, -P, -n, -o…

Примеры

# PID процессов с именем ровно nginx
pgrep -x nginx

# с полными командными строками
pgrep -a python3

# по аргументам: процесс, запущенный с конкретным конфигом
pgrep -af 'worker --queue=mail'

# сколько процессов у пользователя
pgrep -c -u www-data

# самый новый процесс ssh
pgrep -n -x sshd

# PID через запятую — для ps -p
ps -o pid,etime,cmd -p "$(pgrep -d, -x cron)"

# запущен ли процесс — в условии
if pgrep -x cron >/dev/null; then echo "cron работает"; fi

# остановленные (T) процессы
pgrep -a -r T

# перечитать конфиг всем процессам по имени
pkill -HUP -x nginx

# завершить процессы пользователя и показать, кого
pkill -e -u alice

# убить по командной строке
pkill -f 'sleep 1000'

Самосовпадение -f и трюк со скобками

pgrep -f смотрит на командные строки всех процессов. Если pgrep запущен из bash -c '…' (или из скрипта), строка этой оболочки тоже содержит шаблон — и pgrep найдёт её. Сам себя pgrep исключает, свою родительскую оболочку — нет:

bash -c "pgrep -af 'sleep 777'; true"
# 9 bash -c pgrep -af 'sleep 777'; true     ← процесса sleep 777 нет, а «нашёлся»

Так проверка «процесс запущен» всегда успешна, а «процесс остановлен» — всегда проваливается. Лечится квадратными скобками в шаблоне:

pgrep -f '[s]leep 777'

Регулярка [s]leep совпадает со строкой sleep, но в командной строке оболочки записано [s]leep — сама с собой она уже не совпадает. Тот же приём работает с ps aux | grep '[n]ginx'. Другой вариант — pgrep -A, который пропускает всех предков pgrep.

Подводные камни

  • Имя процесса — не больше 15 символов. pgrep averyverylongname_sleeper ничего не найдёт (и предупредит об этом). Используй -f или первые 15 символов.
  • Без -x шаблон — подстрока. pkill ssh убьёт и sshd, и твою собственную ssh-сессию. Для pkill почти всегда добавляй -x или точный -f.
  • Шаблон — регулярка. Точка значит «любой символ», + и ( — спецсимволы. pgrep -f 'app.py' найдёт и appXpy.
  • -f совпадает и с чужими строками: редактор, открывший файл worker.conf, найдётся по шаблону worker. Делай шаблон конкретнее.
  • Самосовпадение с оболочкой — см. выше: в скриптах и bash -c с несколькими командами используй [x]yz или -A.
  • pkill без сигнала шлёт TERM, а не KILL. Процесс может его перехватить и не завершиться.

См. также

ps · kill · regex · proc