Как получить дочерний процесс из родительского процесса
Можно ли получить идентификатор дочернего процесса из идентификатора родительского процесса в сценарии оболочки?
У меня есть файл для выполнения с помощью сценария оболочки, который приводит к новому процессу process1 (родительский процесс). Этот процесс1 разветвил другой процесс process2(дочерний процесс). Используя скрипт, я могу получить pid для process1 с помощью команды:
cat /path/of/file/to/be/executed
но я не могу получить pid дочернего процесса.
11 ответов
Я не уверен, правильно ли я вас понимаю, это помогает?
ps --ppid <pid of the parent>
Я написал scrpit, чтобы получить все pids дочернего процесса родительского процесса. Вот код. Надеюсь, это поможет.
function getcpid() {
cpids=`pgrep -P $1|xargs`
# echo "cpids=$cpids"
for cpid in $cpids;
do
echo "$cpid"
getcpid $cpid
done
}
getcpid $1
Чтобы получить дочерний процесс и поток,pstree -p PID
, Это также показывает иерархическое дерево
Вы можете получить pids
всех дочерних процессов данного родительского процесса <pid>
прочитав /proc/<pid>/task/<tid>/children
вход.
Этот файл содержит идентификаторы дочерних процессов первого уровня.
Для получения дополнительной информации перейдите на https://lwn.net/Articles/475688/.
Процесс оболочки $$
так как это особый параметр
В Linux файловая система proc(5) предоставляет много информации о процессах. Возможно, pgrep (1) (который обращается к /proc
) тоже может помочь.
Так что постарайтесь cat /proc/$$/status
чтобы получить статус процесса оболочки.
Следовательно, его идентификатор родительского процесса может быть получен с помощью, например,
parpid=$(awk '/PPid:/{print $2}' /proc/$$/status)
Тогда используйте $parpid
в вашем скрипте ссылаться на родительский процесс pid (родительский shell).
Но я не думаю, что вам это нужно!
Прочтите руководство по Bash (или с осторожностью - руководство по написанию сценариев Bash, в котором есть ошибки) и расширенное программирование в Linux.
Обратите внимание, что некоторые процессы демона сервера (которые обычно должны быть уникальными) явно записывают свой pid в /var/run
например, sshd
демон сервера записывает свой pid в текстовый файл /var/run/sshd.pid
). Возможно, вы захотите добавить такую функцию в ваши собственные серверные программы (написанные на C, C++, Ocaml, Go, Rust или каком-либо другом скомпилированном языке).
ps -axf | grep parent_pid
Выше команда печатает соответствующие процессы, сгенерированные из parent_pid
, Надеюсь, поможет.
+++++++++++++++++++++++++++++++++++++++++++
root@root:~/chk_prgrm/lp#
parent...18685
child... 18686
root@root:~/chk_prgrm/lp# ps axf | grep frk
18685 pts/45 R 0:11 | \_ ./frk
18686 pts/45 R 0:11 | | \_ ./frk
18688 pts/45 S+ 0:00 | \_ grep frk
Вы можете распечатать PID всех дочерних процессов, вызванных родительским процессом:
pstree -p <PARENT_PID> | grep -oP '\(\K[^\)]+'
Это рекурсивно печатает список pid для основного процесса и его дочерних элементов.
Я использовал следующее, чтобы собрать родительский процесс и дочерние процессы определенного процесса PID:
ps -p $PID --ppid $PID --forest | tail -n +2 | awk '{print$1}'
Обратите внимание, что это не сработает для поиска дочерних процессов дочерних процессов.
В случае, когда интересующее дерево процессов имеет более двух уровней (например, Chromium порождает четырехуровневое дерево процессов), pgrep
не имеет особого смысла. Как уже упоминалось выше, файлы procfs содержат всю информацию о процессах, и их просто нужно прочитать. Я создал инструмент командной строки под названием Procpath, который делает именно это. Читает все/proc/N/stat
files, представляет содержимое в виде дерева JSON и предоставляет его для запросов JSONPath.
Чтобы получить PID всех дочерних процессов, разделенных запятыми, для некорневого процесса (для корневого это ..stat.pid
) его:
$ procpath query -d, "..children[?(@.stat.pid == 24243)]..pid"
24243,24259,24284,24289,24260,24262,24333,24337,24439,24570,24592,24606,...
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
// Create a child process
int pid = fork();
if (pid > 0)
{
int j=getpid();
printf("in parent process %d\n",j);
}
// Note that pid is 0 in child process
// and negative if fork() fails
else if (pid == 0)
{
int i=getppid();
printf("Before sleep %d\n",i);
sleep(5);
int k=getppid();
printf("in child process %d\n",k);
}
return 0;
}