How to send a simple string between two programs using pipes?

后端 未结 7 914
渐次进展
渐次进展 2020-11-22 12:17

I tried searching on the net, but there are hardly any resources. A small example would suffice.

EDIT I mean, two different C programs communicating with each other.

相关标签:
7条回答
  • 2020-11-22 12:18

    What one program writes to stdout can be read by another via stdin. So simply, using c, write prog1 to print something using printf() and prog2 to read something using scanf(). Then just run

    ./prog1 | ./prog2
    
    0 讨论(0)
  • 2020-11-22 12:27

    From Creating Pipes in C, this shows you how to fork a program to use a pipe. If you don't want to fork(), you can use named pipes.

    In addition, you can get the effect of prog1 | prog2 by sending output of prog1 to stdout and reading from stdin in prog2. You can also read stdin by opening a file named /dev/stdin (but not sure of the portability of that).

    /*****************************************************************************
     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);
    }
    
    0 讨论(0)
  • 2020-11-22 12:31

    Here's a sample:

    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;
    }
    

    The important steps in this program are:

    1. The popen() call which establishes the association between a child process and a pipe in the parent.
    2. The fprintf() call that uses the pipe as an ordinary file to write to the child process's stdin or read from its stdout.
    3. The pclose() call that closes the pipe and causes the child process to terminate.
    0 讨论(0)
  • 2020-11-22 12:32
    dup2( STDIN_FILENO, newfd )
    

    And read:

    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 );    
    

    But, I think that fcntl can be a better solution

    echo "salut" | code
    
    0 讨论(0)
  • 2020-11-22 12:33

    First, have program 1 write the string to stdout (as if you'd like it to appear in screen). Then the second program should read a string from stdin, as if a user was typing from a keyboard. then you run:

    $ program_1 | program_2
    
    0 讨论(0)
  • 2020-11-22 12:35

    This answer might be helpful for a future Googler.

    #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;
    
    }
    

    You can find an advanced two-way pipe call example here.

    0 讨论(0)
提交回复
热议问题