2016-06-01 7 views
0

Ich bin neu mit Bash. Ich habe diesen kleinen Code:
bash.shBash: Erhalten Kind Prozessname

./mama 

mama.cpp

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

shvili.cpp

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

Wie es zeigt mir mama ist Elternteil von shvili Prozess. Ich habe eine Situation wie diese, wo ich nicht genau den Namen des Kindprozesses weiß. Meine Frage ist also, wie kann ich die PID des Child-Prozesses von C++ bekommen? (Es wäre bequemer für mich, den Namen des Prozesses zu bekommen).

+0

warum nicht fork + exec statt Systemaufruf verwenden? – sanjayk79

Antwort

1

Ein Weg über bash in case „Situation wie dieser, wo ich weiß nicht genau mit dem Namen des Kindes Prozess“, um zumindest zu prüfen, aber kennt den Namen des übergeordneten Prozesses angenommen werden einzigartige, kann man in bash basierend auf ps verwenden, grep, sed (für kleinere PIDs führenden Raum zu entfernen), tr (multiple consecuting Räume in eine drücken) und 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 

So ist der eindeutige Name des übergeordneten Prozesses wird verwendet, um die Mutter pid zu bestimmen:

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

Diese in einem Teilprozess ausgewertet ($(...)) verwendet wird, um die richtige Linie von einem anderen ps Aufruf grep die seeked pid von zu bestimmen, Kind und Name (ohne zusätzliche Argumente und ohne vorherige Kenntnis des Namens des Kindes.

Hinweis - wie in bash gewohnt einige Räume sind wichtig - der zusätzliche Raum am Ende des Suchmusters:

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

Diese Fehlalarme vermeiden hilft, wie wenn ein Elternteil pid 123, ohne Polsterung mit Räume würde dies viele pids übereinstimmen, die diese Ziffern wie 1234, 12345, 1123, enthalten ...

aktualisieren (auf Kommentar reagieren): bei übergeordneten Prozess a_mama wird (abzweigt a_shvili Sub-Prozess) und es ist die Nur mit diesem Namen auf der Maschine verarbeiten, dann die Folgendes sollte funktionieren:

$> 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

Ich weiß, dass dies keine C++ - Lösung ist, aber wie bereits erwähnt, kann es sich als nützlich erweisen, um einen Test durchzuführen oder wenn kein Zugriff auf den Quellcode möglich ist. – Dilettant

+0

nachdem ich 'sleep 120' in' mama' verwandelt habe 'ps -eo pid, ppid, args | grep -e" $ (ps -o pid, args | grep foo_bar.sh | grep -v grep | cut -f 1 - d '') "| grep -v foo_bar.sh | cut -f 1,3-d '' 'gibt mir eine Ausgabe mit vielen PIDs – Ojs

+0

Oh, ich verstehe, aber 'foo_bar.sh' war ein Mock, der für deinen' Mama' ** Elternprozess stand und somit "Schlaf" 120' wäre das ** Kind ** ('shvili' in deiner Frage), also solltest du' Mama' (als Eltern) im Hintergrund starten oder dann in einem anderen Terminal 'foo_bar.sh' in meinem Rezept mit' Mama ersetzen '(in der Hoffnung, es passt nicht zu viele Prozessnamen läuft ... – Dilettant

0

können Sie versuchen, pidof verwenden, um die PID eines bestimmten Prozesses zu erhalten.

Beispiel

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

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

pclose(cmd); 
0

Sie wissen, tun Sie den Namen des Kindes Prozess ist es shvili, wie können Sie es starten und nicht wissen, seinen Namen.

Wenn Sie die PID des Kindes kennen, dann verwenden Sie nicht system. system ist kein gut erzogenes Verfahren, benutze es nicht.

Verwenden Sie stattdessen fork und exec:

In Eltern tun:

#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(…); 
} 

Erläuterung:

  • der erste Zweig der ifs läuft, wenn Gabel Fehler.
  • sonst
    • In 2 getrennten Prozessen:
    • die zweite Zweig läuft für das Kind.
    • und der dritte Zweig wird für den übergeordneten Zweig ausgeführt.
+0

Ich habe nur ein Beispiel gezeigt, wie die Situation sein könnte Ich habe einen Prozess, der verschiedene Child auf verschiedenen Distributionen hat (weil er ein anderes Bash Script ausführt) wenn es beginnt), möchte ich den Namen des Kindprozesses bekommen. – Ojs

+0

Sie sti Ich muss es wissen, um 'System' oder 'Exec' zu nennen, ist es in einer Variablen? Welche Teile kennen Sie? Welche Teile müssen Sie kennen? –

+0

Es ist nur ein Beispiel. In Wirklichkeit habe ich einen Prozess, der Sitzung für verschiedene Benutzer erstellt. Auf gnome ist das Kind 'init --user ', aber zum Beispiel auf Centos, dem' gnome-session'-Prozess, muss ich einen Code schreiben, der mir sagen würde, welches davon das Kind ist – Ojs