2016-12-27 3 views
1

Ich bin sehr Neuling über Rohre und ich möchte ein kleines Programm für das Verständnis und lernen darüber zu entwickeln. Meine Idee besteht darin, Kommando Shell cat to wc mit c zu kommunizieren. Ich habe ein sehr einfaches Programm gemacht, das eine existierende Datei verwendet (test.txt zum Beispiel), aber im Moment kann ich nur den Inhalt anzeigen. Ich möchte nur die Anzahl der Zeilen um eine bestimmte Datei zählen.Transformiere cat file.txt | wc -l Programmcode c

Ist dies möglich? Oder muss ich vielleicht eine andere Option machen? Hier ist mein Grundcode:

int main(int argc, char *argv[]) { 
    pid_t pid; 
    int fd[2]; 

    pipe(fd); 
    pid = fork(); 

    if (pid == -1) { 
     perror("fork"); 
     exit(1);  
    } 

    if (pid == 0) { 
     /* Child process closes up input side of pipe */ 
     close(fd[0]); 
     execlp("cat", "cat", "test.txt", NULL); 
     //I don't know how communicate this process with the other process 
    } else { 
     /* Parent process closes up output side of pipe */ 
     close(fd[1]); 
     execlp("wc", "wc", "-l", NULL); 
    } 
} 
+0

können Sie eine der Antworten akzeptieren, indem Sie auf das graue Häkchen unter der Punktzahl klicken. – chqrlie

Antwort

2

Sie müssen das entsprechende Ende des Rohrs zu der Standardeingabe und/oder Standard-Ausgabe vor dem Aufruf von execlp() umleiten. Wenn dieser Aufruf erfolgreich ist, wurde der aktuelle Prozess durch den neuen ersetzt, es wird kein weiterer Code ausgeführt, aber wenn es fehlschlägt, sollten Sie sich mit einem perror() beschweren. Hier

ist eine korrigierte Version des Codes:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main (int argc, char *argv[]) { 
    pid_t pid; 
    int fd[2]; 

    if (pipe(fd)) { 
     perror("pipe"); 
     return 1; 
    } 

    pid = fork(); 
    if (pid == -1) { 
     perror("fork"); 
     return 1; 
    } 

    if (pid == 0) { 
     /* Child process redirects its output to the pipe */ 
     dup2(fd[1], 1); 
     close(fd[0]); 
     close(fd[1]); 
     execlp("cat", "cat", "test.txt", NULL); 
     perror("exec cat"); 
     return 1; 
    } else { 
     /* Parent process redirects its input from the pipe */ 
     dup2(fd[0], 0); 
     close(fd[0]); 
     close(fd[1]); 
     execlp("wc", "wc", "-l", NULL); 
     perror("exec wc"); 
     return 1; 
    } 
} 
+0

Vielen Dank :) Funktioniert perfekt! – vikitus

+0

Eine Frage: Warum double close (fd [0]) und close (fd [1]) ?? – vikitus

+0

@vikitus: 'fd [0]' und 'fd [1]' werden vor dem Systemaufruf 'execlp' geschlossen, um zu verhindern, dass der nächste Prozess diese Handles erbt. Das entsprechende Ende der Pipe wurde in die Standardeingabe oder -ausgabe dupliziert, die ursprünglichen Pipe-Handles werden im aktuellen Prozess nicht mehr verwendet und sollten nicht an den ausgeführten Prozess übergeben werden. – chqrlie

0

, wenn Sie über die Anzahl der Zeilen in der Datei kümmern können Sie einfach den gesamten Befehl ausführen popen verwenden und dann die Ausgabe für die Ausgabe lesen oder einem Fehler

e.g. fd = popen("cat test.txt | wc -l", "r"); 

Verwenden Sie dann read Methode, um den Ausgang zu lesen. Sie können auch den Rückgabewert von pclose(fd) verwenden, um zu überprüfen, ob der Prozess erfolgreich abgeschlossen wurde.

Verwandte Themen