Я хотел бы получить список всех процессов, которые происходят (например, дети, внуки и т. Д.) $pid
. Это самый простой способ, которым я придумал:
pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"
Есть ли какая-либо команда или более простой способ получить полный список всех процессов-потомков?
'\n'
разделитель и' '
разделитель). Практический пример использования: а) сценарий демона, который я написал из чистого мазохизма (в частности, функциональность «стоп» должна иметь дело с любым деревом процессов, порожденных демонизированным процессом); и b) сценарий тайм-аута, который уничтожит все, что удалось создать процессу тайм-аута.kill
. См. Unix.stackexchange.com/questions/9480/… , unix.stackexchange.com/questions/50555/…ps ax -opid,ppid,pgrp,cmd
Я вижу, что есть много процессов, которые разделяют то же самое,pgrp
что и точное поддерево, которое я хочу убить. (Кроме того, я нигде не вижуsetpgrp
программу, указанную в стабильных пакетах debian: packages.debian.org/… )Ответы:
Следующее несколько проще и имеет дополнительное преимущество, заключающееся в игнорировании чисел в именах команд:
Или с Perl:
Мы ищем числа в скобках, чтобы мы, например, не давали 2 как дочерний процесс при нашей работе
gif2png(3012)
. Но если в имени команды указан номер в скобках, все ставки отключены. Там только пока обработка текста может взять вас.Поэтому я также считаю, что группы процессов - это путь. Если вы хотите, чтобы процесс выполнялся в собственной группе процессов, вы можете использовать инструмент pgrphack из пакета Debian 'daemontools':
Или вы можете снова обратиться к Perl:
Единственное предостережение здесь заключается в том, что группы процессов не вкладываются, поэтому, если какой-то процесс создает свои собственные группы процессов, его подпроцессы больше не будут находиться в созданной вами группе.
источник
pstree -lp | grep -Po "(?<=\()\d+(?=\))"
источник
bash
,zsh
,fish
, и дажеksh 99
), но может не работать на старых снарядах, напримерksh 88
Самая короткая версия, которую я нашел, также правильно работает с такими командами, как
pop3d
:Речь идет неправильно , если у вас есть команды , которые имеют странные имена , как:
my(23)prog
.источник
ffmpeg
использованием потоков. Хотя, из быстрых наблюдений, кажется , что нити даны с их именем внутри фигурных скобок{ }
.Существует также проблема правильности. Наивный анализ вывода
pstree
проблематичен по нескольким причинам:Если у вас есть Python и
psutil
установленный пакет, вы можете использовать этот фрагмент, чтобы перечислить все процессы-потомки:(Пакет psutil устанавливается, например, как зависимость от
tracer
команды, доступной в Fedora / CentOS.)В качестве альтернативы вы можете выполнить обход дерева процессов в ширину в оболочке Bourne:
Для вычисления транзитивного замыкания пида хвостовая часть может быть опущена.
Обратите внимание, что приведенное выше не использует рекурсию и также работает в ksh-88.
В Linux можно исключить
pgrep
вызов и вместо этого прочитать информацию из/proc
:Это более эффективно, потому что мы сохраняем один форк / exec для каждого PID и
pgrep
выполняем некоторую дополнительную работу в каждом вызове.источник
Эта версия Linux требует только / proc и ps. Это адаптировано из последней части превосходного ответа @ maxschlepzig . Эта версия читает / proc непосредственно из оболочки вместо порождения подпроцесса в цикле. Это немного быстрее и, возможно, немного более элегантно, как этого требует заголовок темы.
источник
Почему в каждом из ваших двух (казалось бы, очень искусственных) вариантов использования вы хотите убить подпроцессы какого-нибудь неудачного процесса? Как вы знаете лучше, чем процесс, когда его дети должны жить или умереть? Это кажется плохим дизайном для меня; процесс должен убирать за собой.
Если вы действительно знаете лучше, тогда вы должны отказаться от этих подпроцессов, и «демонизированный процесс», очевидно, слишком глуп, чтобы ему доверять
fork(2)
.Вам следует избегать хранения списков дочерних процессов или обхода дерева процессов, например, помещая дочерние процессы в отдельную группу процессов, как предложено @Gilles.
В любом случае, я подозреваю, что вашему демонизированному процессу было бы лучше создать пул рабочих потоков (который обязательно умирает вместе с процессом, в котором он содержится), чем глубокое дерево подпод-подпроцессов, которое затем нужно что-то очистить ,
источник
Вот скрипт-обертка pgrep, который позволяет вам использовать pgrep и получать всех потомков одновременно.
~/bin/pgrep_wrapper
:Вызывайте так же, как и обычный pgrep, например,
pgrep_recursive -U $USER java
чтобы найти все процессы и подпроцессы Java от текущего пользователя.источник
IFS
и использованием массивов ("${array[*]}
").