Список процессов, запущенных в заданном каталоге

#linux #unix #ps #getcwd

#linux #unix #ps #getcwd

Вопрос:

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

Это означает, что они должны быть удалены грубо (с SIGTERM помощью ), а затем, для особо упрямых — жестоко (с SIGKILL помощью ).

Проблема в том, чтобы найти их все… Как вы перечисляете все процессы, которые рассматривают данный каталог — или его подкаталог — его рабочий каталог ( cwd )?

Лучший метод, который я смог придумать, состоял в том, чтобы вызвать: lsof -b -w -u $(whoami) , затем проанализировать последний столбец в поисках моего каталога, а затем запустить второй столбец (the PID ) sort -u .

Может быть, есть что-нибудь лучше?

Комментарии:

1. Это давно работающая системная служба? Если это так, попробуйте использовать систему инициализации, например systemd, для управления процессом. Systemd доступен в современных дистрибутивах Debian и Red Hat и выполняет все это и многое другое. Вы не хотите изобретать велосипед, если в этом нет необходимости.

Ответ №1:

Если вас интересуют только рабочие каталоги, вы можете использовать awk для проверки, является ли 4-й столбец выходных cwd данных. А awk также можете проверить последний столбец, чтобы узнать, находится ли он в интересующем вас каталоге.

 procs=$(lsof -b -w -u $(whoami)  | awk '$4 == "cwd" amp;amp; $NF ~ /^/path/to/directory(/|$)/ { print $2 }')
 

Поскольку каждый процесс имеет только одну cwd ссылку, вам не нужно использовать sort -u для удаления дубликатов.

Комментарии:

1. Ограничение на $4 == "cwd" — хорошая идея, но в целом этот вариант не работает — по крайней мере, на RHEL7 — потому что using -b и явный каталог являются взаимоисключающими: lsof не stat будет каталога, поскольку это «потенциально блокирует». Он также не будет перечислять процессы, работающие в подкаталоге данного каталога, который я также хочу уничтожить — отсюда синтаксический анализ последнего столбца…

2. Хорошо, я изменил его, чтобы проверить наличие каталога awk . Это также позволяет ему находить подкаталоги.

3. Да, @barmar, это то, что я делаю, но мне было интересно, есть ли лучший способ сделать это — pwdx pgrep например, какой-нибудь трюк или…

4. Не то, чтобы я знал, поскольку это не то, что обычно требуется.

Ответ №2:

Предполагая типичную среду Linux с файловой системой procfs, установленной в /proc :

 #!/usr/bin/env bash

# Script takes the desired directory as its argument and prints out
# all pids with that directory or a child directory as their working
# directory (As well as what the cwd is)

shopt -s extglob

dir=${1#/}

for p in /proc/[0-9]*; do
    cwd=$(readlink -m "$p/cwd")
    if [[ ${cwd#/} == $dir?(/*) ]]; then
       printf "%dt%sn" "${p#/proc/}" "$cwd"
    fi
done
 

Комментарии:

1. Спасибо, это тоже может сработать… Лично я предпочитаю такой lsof подход, поскольку он, скорее всего, будет работать за пределами мира Linux. Но я надеялся на какое-то разумное использование pwdx or pgrep