2016-06-01 2 views
0

Я новичок в bash. Я есть этот маленький код:
bash.shBash: Получить имя дочернего процесса

./mama 

mama.cpp

#include <stdlib.h> 
int main() 
{ 
    system("./shvili"); 
    while(1){} 
} 

shvili.cpp

int main() 
{ 
    while(1){} 
} 

Как показывает мне mama является родителем shvili процесс. У меня такая ситуация, когда я точно не знаю имя дочернего процесса. Поэтому мой вопрос: как я могу получить PID дочернего процесса из C++? (Мне было бы удобнее получить имя процесса).

+0

Почему бы не использовать fork + exec вместо системного вызова? – sanjayk79

ответ

1

Способ по крайней мере, проверить с помощью Баша в случае «ситуацию, как это, где я не знаю точно названия дочернего процесса», но знаю, что имя родительского процесса предполагается уникальный, можно использовать в bash на основе ps, grep, sed (удалить начальный пробел для небольших PIDs), tr (сжать несколько consecuting пространства в один), и cut:

$> cat foo_bar.sh 
#! /bin/bash 
sleep 120 

$> ./foo_bar.sh & 
[1] 89239 

$> ps -eo pid,ppid,args|grep -e " $(ps -eo pid,args| grep foo_bar.sh| grep -v grep| sed s/^\ //g |cut -f 1 -d ' ') "|grep -v foo_bar.sh| sed s/^\ //g | tr -s ' ' | cut -f 1,3 -d ' ' 
89241 sleep 

Таким образом, уникальное имя родительского процесса используется для определения родительского PID:

$> ps -eo pid,args| grep foo_bar.sh| grep -v grep| sed s/^\ //g |cut -f 1 -d ' ' 
89239 

В этом оценивало в процессе суба ($(...)) используются для ГРЭП правильной линии от другого ps вызова, чтобы определить добившийся PID из child и name (без дополнительных аргументов и без предварительного знания имени childs.

Примечание - как обычно в Баш некоторые пробелы важны - дополнительное пространство в конце шаблона поиска:

... grep " $(ps -eo pid,args| grep foo_bar.sh| grep -v grep| cut -f 1 -d ' ') " ... 

Это помогает избежать ложных срабатываний, например, когда родитель ПИД- 123, без дополнения с пространства это будет соответствовать много ИДПА, которые содержат эти цифры, как 1234, 12345, 1123, ...

Update (реагируя на комментарии): В случае, если родительский процессе a_mama (разветвление от a_shvili процесса к югу) и является только процесс с этим именем на машине, затем должно работать:

$> p_proc="a_mama" 
$> ps -eo pid,ppid,args|grep -e " $(ps -eo pid,args| grep ${p_proc}| grep -v grep| sed s/^\ //g | cut -f 1 -d ' ') "|grep -v ${p_proc}| sed s/^\ //g | tr -s ' ' | cut -f 1,3 -d ' ' 
12346 a_shvili 
+0

Я знаю, что это не C++-решение, но, как отмечено, может оказаться полезным для тестирования или когда не предоставляется доступ к исходному коду. – Dilettant

+0

после того, как я изменил 'sleep 120' на' mama' 'ps -eo pid, ppid, args | grep -e '$ (ps -eo pid, args | grep foo_bar.sh | grep -v grep | cut -f 1 - d '') "| grep -v foo_bar.sh | cut -f 1,3 -d '' 'дает мне выход с большим количеством PID – Ojs

+0

О, я вижу, но 'foo_bar.sh' был макетным для вашего родительского процесса ** mama' ** и таким образом' sleep 120' будет ** дочерним ** ('shvili' в вашем вопросе), поэтому вы должны запустить' mama' (как родительский) в фоновом режиме, а затем на другом терминале заменить 'foo_bar.sh' в моем рецепте' mama '(в надежде, что он соответствует не слишком многим именам процессов, запущенным ... – Dilettant

0

вы можете попробовать использовать pidof, чтобы получить pid определенного процесса.

Пример

char line[LEN]; 
FILE *cmd = popen("pidof...", "r"); 

fgets(line, LEN, cmd); 
pid_t pid = strtoul(line, NULL, 10); 

pclose(cmd); 
0

Ты знаешь имя дочернего процесса является shvili, как вы можете запустить его и не знаю его имени.

Если вы хотите знать PID ребенка, тогда не используйте system. system не очень хорошо себя ведет, не используйте.

Вместо этого используйте fork и exec:

В родителе сделать:

#include <unistd.h> 

int child_pid = fork(); 
if (child_pid == -1) { 
    //fork failed do something about it 
} else if (child_pid == 0) { 
    //this runs for child 
    execl("shvili", NULL); 
    //if you get here then exec errored 
} else { 
    //This runs for parent 
    //child_pid has child pid 
    //Add parent code hear. 
    wait(…); 
} 

Объяснение:

  • первой ветвь МФСА работает, если вилочные ошибки.
  • еще
    • В 2 отдельные процессы:
    • второй ветви прогонов для ребенка.
    • и третья ветвь работает для родителя.
+0

Я показал пример, как может быть ситуация. У меня есть процесс, который имеет различный дочерний элемент на разных дистрибутивах (поскольку он выполняет разные сценарии bash когда он начинается), я хочу получить имя дочернего процесса. – Ojs

+0

You sti Должен ли я это знать, чтобы вызвать 'system' или' exec', это в переменной? Какие части знают ?, какие части должны знать? –

+0

Его просто пример. На самом деле у меня есть процесс, который создает сеанс для разных пользователей. В gnome это дочерний элемент 'init -user', но, например, в centos его процесс' gnome-session', я должен написать код, который даст мне, какой из них является дочерним – Ojs

Смежные вопросы