Wie sende ich eine einfache Zeichenfolge zwischen zwei Programmen mit Pipes?

Lesezeit: 6 Minuten

Ich habe versucht, im Netz zu suchen, aber es gibt kaum Ressourcen. Ein kleines Beispiel würde genügen.

BEARBEITEN Ich meine, zwei verschiedene C-Programme kommunizieren miteinander. Ein Programm sollte “Hi” senden und das andere sollte es empfangen. Sowas in der Art.

  • Vermutlich meinst du nicht so etwas wie ls | grep ".o"? Vielleicht würde eine etwas genauere Erklärung, was du meinst, helfen …

    – Jerry Sarg

    6. Mai 2010 um 21:09 Uhr


  • Komm schon, Mann … ein bisschen Mühe. Google “C-Pipes-Beispielcode”. Das erste Ergebnis ist exakt: tldp.org/LDP/lpg/node11.html

    – Stefan

    6. Mai 2010 um 21:12 Uhr

  • Ich möchte die Kommunikation zwischen zwei völlig unterschiedlichen Programmen. Ich konnte keine Ressource dafür finden.

    Benutzer244333

    6. Mai 2010 um 21:16 Uhr

  • Wenn Sie keinen Prozess forken, müssen Sie sich “benannte Pipes” ansehen.

    – Richter Maygarden

    7. Mai 2010 um 13:49 Uhr


Benutzeravatar von jschmier
jschmier

Eine normale Pipe kann nur zwei verwandte Prozesse verbinden. Es wird von einem Prozess erstellt und verschwindet, wenn der letzte Prozess es schließt.

EIN benanntes Rohr, aufgrund seines Verhaltens auch als FIFO bezeichnet, kann verwendet werden, um zwei voneinander unabhängige Prozesse zu verbinden, und existiert unabhängig von den Prozessen; was bedeutet, dass es existieren kann, auch wenn niemand es benutzt. Ein FIFO wird mit dem erstellt mkfifo() Bibliotheksfunktion.

Beispiel

Schriftsteller.c

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";

    /* create the FIFO (named pipe) */
    mkfifo(myfifo, 0666);

    /* write "Hi" to the FIFO */
    fd = open(myfifo, O_WRONLY);
    write(fd, "Hi", sizeof("Hi"));
    close(fd);

    /* remove the FIFO */
    unlink(myfifo);

    return 0;
}

Leser.c

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAX_BUF 1024

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    read(fd, buf, MAX_BUF);
    printf("Received: %s\n", buf);
    close(fd);

    return 0;
}

Hinweis: Der Einfachheit halber wurde im obigen Code die Fehlerprüfung weggelassen.

  • Was gilt zusammenhängende Prozesse?

    – Pithikos

    29. August 2014 um 18:00 Uhr

  • Wahrscheinlich Prozesse, die über eine oder mehrere Eltern/Kind-Beziehungen verwandt sind (z. B. Geschwister enthalten). Der gemeinsame Vorfahre hätte die beiden Enden des Rohres geschaffen. Unabhängigen Prozessen fehlt dieser gemeinsame Vorfahre.

    – MSalter

    5. November 2014 um 15:58 Uhr

  • Dies funktioniert nicht, wenn der Leser zuerst loslegt. Eine schnelle Lösung wäre, die zu setzen open() des Lesers in einer Schleife. +1 jedoch, weil Sie ein Beispiel mit zwei Programmen bereitstellen.

    – Gsamaras

    15. November 2014 um 12:12 Uhr


  • Ich nehme an, dieses Beispiel muss etwas angepasst werden, um unter Windows zu funktionieren? unistd.h ist POSIX und alles …

    – David Karlson

    4. März 2015 um 12:01 Uhr

  • Ja, es muss für Windows optimiert werden. Das Wikipedia-Artikel über Named Pipes bespricht einige der Unix/Windows-Unterschiede und eine schnelle Google-Suche kann bei der Windows-Implementierung helfen.

    – jschmier

    4. März 2015 um 16:46 Uhr

Benutzeravatar von Stephen
Stefan

Aus Erstellen von Pipes in C, dies zeigt Ihnen, wie Sie ein Programm forken, um eine Pipe zu verwenden. Wenn Sie nicht fork() möchten, können Sie verwenden benannte Rohre.

Darüber hinaus können Sie die Wirkung von erhalten prog1 | prog2 durch Senden der Ausgabe von prog1 zu stdout und Lesen von stdin in prog2. Sie können stdin auch lesen, indem Sie eine Datei mit dem Namen öffnen /dev/stdin (aber nicht sicher über die Portabilität davon).

/*****************************************************************************
 Excerpt from "Linux Programmer's Guide - Chapter 6"
 (C)opyright 1994-1995, Scott Burkett
 ***************************************************************************** 
 MODULE: pipe.c
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd);

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

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, (strlen(string)+1));
                exit(0);
        }
        else
        {
                /* Parent process closes up output side of pipe */
                close(fd[1]);

                /* Read in a string from the pipe */
                nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);
        }

        return(0);
}

  • Hey Stephen, trotzdem kann ich diesen Code für zwei verschiedene Funktionen verwenden? Das heißt, das Schreiben in die Pipe erfolgt in einer Funktion und das Lesen der Pipe in einer anderen Funktion? Ein funktionierender Code wie dieser wäre wünschenswert.

    – Mohsin

    8. September 2016 um 15:40 Uhr

Benutzeravatar von mlouk
Blick

dup2( STDIN_FILENO, newfd )

Und lese:

char reading[ 1025 ];
int fdin = 0, r_control;
if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}
memset( reading, '\0', 1025 );
while( ( r_control = read( fdin, reading, 1024 ) ) > 0 ){
    printf( "<%s>", reading );
    memset( reading, '\0', 1025 );
}
if( r_control < 0 )
    perror( "read(  )" );    
close( fdin );    

Aber ich denke das fcntl kann eine bessere Lösung sein

echo "salut" | code

Was ein Programm auf stdout schreibt, kann von einem anderen über stdin gelesen werden. Also einfach mit c schreiben prog1 etwas drucken mit printf() und prog2 etwas lesen mit scanf(). Dann lauf einfach

./prog1 | ./prog2

Benutzeravatar von Preet Sangha
Preet-Sangha

Hier ist ein Beispiel:

int main()
{
    char buff[1024] = {0};
    FILE* cvt;
    int status;
    /* Launch converter and open a pipe through which the parent will write to it */
    cvt = popen("converter", "w");
    if (!cvt)
    {
        printf("couldn't open a pipe; quitting\n");
        exit(1)
    }
    printf("enter Fahrenheit degrees: " );
    fgets(buff, sizeof (buff), stdin); /*read user's input */
    /* Send expression to converter for evaluation */
    fprintf(cvt, "%s\n", buff);
    fflush(cvt);
    /* Close pipe to converter and wait for it to exit */
    status=pclose(cvt);
    /* Check the exit status of pclose() */
    if (!WIFEXITED(status))
        printf("error on closing the pipe\n");
    return 0;
}

Die wichtigen Schritte in diesem Programm sind:

  1. Das popen() -Aufruf, der die Zuordnung zwischen einem untergeordneten Prozess und einer Pipe im übergeordneten Prozess herstellt.
  2. Das fprintf() Aufruf, der die Pipe als gewöhnliche Datei verwendet, um in die Standardeingabe des untergeordneten Prozesses zu schreiben oder von seiner Standardausgabe zu lesen.
  3. Das pclose() -Aufruf, der die Pipe schließt und bewirkt, dass der untergeordnete Prozess beendet wird.

  • Ich denke, dieses Beispiel verfehlt den Punkt der Frage, obwohl ich zugebe, dass das “Konverter” -Programm ein anderes Programm ist. Der erste Kommentar befasst sich mit der Kommunikation zwischen vollständig unabhängigen Programmen, die keine Geschwister-/Eltern-/Zweit-Cousin-Beziehung haben.

    – cmm

    9. März 2015 um 16:19 Uhr

Benutzeravatar von Anjana
Anjana

Diese Antwort könnte für einen zukünftigen Googler hilfreich sein.

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

int main(){     
     int p, f;  
     int rw_setup[2];   
     char message[20];      
     p = pipe(rw_setup);    
     if(p < 0){         
        printf("An error occured. Could not create the pipe.");  
        _exit(1);   
     }      
     f = fork();    
     if(f > 0){
        write(rw_setup[1], "Hi from Parent", 15);    
     }  
     else if(f == 0){       
        read(rw_setup[0],message,15);       
        printf("%s %d\n", message, r_return);   
     }  
     else{      
        printf("Could not create the child process");   
     }      
     return 0;

}

Hier finden Sie ein erweitertes Zwei-Wege-Pipe-Call-Beispiel hier.

  • Ich denke, dieses Beispiel verfehlt den Punkt der Frage, obwohl ich zugebe, dass das “Konverter” -Programm ein anderes Programm ist. Der erste Kommentar befasst sich mit der Kommunikation zwischen vollständig unabhängigen Programmen, die keine Geschwister-/Eltern-/Zweit-Cousin-Beziehung haben.

    – cmm

    9. März 2015 um 16:19 Uhr

Benutzeravatar von NAND
NAND

Lassen Sie zuerst Programm 1 den String schreiben stdout (als ob Sie möchten, dass es auf dem Bildschirm erscheint). Dann sollte das zweite Programm einen String aus lesen stdin, als würde ein Benutzer über eine Tastatur tippen. dann führst du aus:

$ program_1 | program_2

1422400cookie-checkWie sende ich eine einfache Zeichenfolge zwischen zwei Programmen mit Pipes?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy