2017-06-29 5 views
0

Ich habe zwei Befehle cmd1 und cmd2 und ich muss cmd1 in einem Kind ausführen, umleiten die Ausgabe zu einem anderen Kind und dann ausführen cmd2 mit der Ausgabe von cmd1 als ein Argument. Dann muss ich die Ausgabe zu einem Remote-Client (Telnet) umleiten, der mit einem Socket verbunden ist. Ich kann das Problem nicht herausfinden, aber meine Lösung leitet die Ausgabe von cmd1 nicht nach cmd2 um.Pipe von zwei Befehlen mit fork, execvp und dann die Ausgabe auf Socket

if(fork() == 0) 
    { 
     //Process to compute cmd1 
     char *arg[2]; 
     arg[0] = cmd1; 
     arg[1] = NULL; 
     dup(piped[1]); 
     close(piped[0]); 
     close(piped[1]); 
     execvp(cmd1,arg); 

    } 
    if(fork() == 0) 
    { 
     //Process to compute cmd2 
     dup2(newsockfd,STDOUT_FILENO); 
     dup2(newsockfd,STDERR_FILENO); 
     char *arg[2]; 
     arg[0] = cmd2; 
     arg[1] = NULL; 
     dup(piped[0]); 
     close(piped[0]); 
     close(piped[1]); 
     execvp(cmd2,arg); 
    } 

Nur um klar zu sein. Das Problem ist nicht in Buchse inizilization oder Rohr, deshalb berichtete ich nur den Hauptteil

+0

wie etwas wäre wollen Warum sollte man etwas erwarten von cmd1 umgeleitet werden ? Sie tun nichts mit der Eingabe oder Ausgabe für diesen untergeordneten Prozess. –

+0

Das ist das Problem. Wie kann der Code debuggen zum Beispiel ein printf, das die Ausgabe von execvp (cmd1, arg) zeigt; im zweiten Kind? –

Antwort

0

Nach meinem Verständnis, was Sie unter

if(fork() == 0) 
{ 
    //Process to compute cmd1 
    char *arg[2]; 
    arg[0] = cmd1; 
    arg[1] = NULL; 
    dup2(piped[1],STDOUT_FILENO); //Redirect stdout to pipe's write end 
    dup2(piped[1],STDERR_FILENO); //Redirect stderr to pipe's write end 
    close(piped[0]); 
    close(piped[1]); 
    close(newsockfd); 
    execvp(cmd1,arg); 
} 

if(fork() == 0) 
{ 
    //Process to compute cmd2 
    char *arg[2]; 
    arg[0] = cmd2; 
    arg[1] = NULL; 
    dup2(piped[0],STDIN_FILENO); //Redirect pipe's read end to stdin 
    dup2(newsockfd,STDOUT_FILENO); //Redirect stdout to socket 
    dup2(newsockfd,STDERR_FILENO); //Redirect stderr to socket 
    close(piped[0]); 
    close(piped[1]); 
    close(newsockfd); 
    execvp(cmd2,arg); 
} 

close(piped[0]); 
close(piped[1]); 
close(newsockfd); 
+0

Ich denke, es ist richtig. Ich habe es versucht, aber es zeigt nichts im Telnet-Konsolen-Client. Die execvp (cmd2, arg); sollte die Ausgabe von execvp (cmd1, arg) haben; als Argument, aber wie ist es mit diesem Code möglich? –

+0

Ab dem Telnet-Teil kann ich mit Ihrem aktuellen Code keine weiteren Schlüsse ziehen. Vielleicht können Sie einfach (newsockfd, "abc", 3) schreiben, um zu sehen, ob es am anderen Ende erscheint. Was den Argumentteil betrifft, habe ich dich vielleicht nicht richtig verstanden. Möchten Sie, dass die Ausgabe von cmd1 (stdout & stderr) das Befehlszeilenargument von cmd2 oder von cmd2 ist? Der obige Code wird das erstere und nicht das letztere erreichen. –

+0

Der Telnet-Client funktioniert. Ich möchte, dass die Ausgabe von cmd1 das Befehlszeilenargument von cmd2 ist. Ich versuche, den normalen Pipe-Befehl in Linux cmd1 | cmd2 zu implementieren. Also führt das erste Kind cmd1 aus, dann führt das zweite Kind cmd2 mit der Ausgabe von cmd1 als Befehlszeilenargument aus. Zum Beispiel ls | sort. Das erste untergeordnete Objekt führt Cmd1 aus, dann wird die Ausgabezeichenfolge an das zweite untergeordnete Objekt übergeben, das die Sortierung mit der Zeichenfolge des ersten untergeordneten Objekts ausführt. –

Verwandte Themen