#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
orpgrep
…