C语言 如何使用管道在两个程序之间发送一个简单的字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2784500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:23:43  来源:igfitidea点击:

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

cunixpipe

提问by jschmier

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. One program should send "Hi" and the other should receive it. Something like that.

编辑我的意思是,两个不同的 C 程序相互通信。一个程序应该发送“Hi”,另一个程序应该接收它。类似的东西。

回答by jschmier

A regular pipe can only connect two related processes. It is created by a process and will vanish when the last process closes it.

一个普通的管道只能连接两个相关的进程。它由一个进程创建,并在最后一个进程关闭它时消失。

A named pipe, also called a FIFO for its behavior, can be used to connect two unrelated processes and exists independently of the processes; meaning it can exist even if no one is using it. A FIFO is created using the mkfifo()library function.

命名管道,也称为FIFO为其行为,可以用于连接两个不相关的进程和独立的处理的存在; 这意味着即使没有人使用它,它也可以存在。FIFO 是使用mkfifo()库函数创建的。

Example

例子

writer.c

作家.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;
}

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

Note: Error checking was omitted from the above code for simplicity.

注意:为简单起见,上面的代码省略了错误检查。

回答by Stephen

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.

在 C 中创建管道,这向您展示了如何分叉程序以使用管道。如果你不想 fork(),你可以使用命名管道

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

此外,您可以prog1 | prog2通过将 的输出发送prog1到 stdout 并从stdinin 中读取来获得效果prog2。您还可以通过打开一个名为/dev/stdin(但不确定它的可移植性)的文件来读取 stdin 。

/*****************************************************************************
 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);
}

回答by mlouk

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, '
echo "salut" | code
', 1025 ); while( ( r_control = read( fdin, reading, 1024 ) ) > 0 ){ printf( "<%s>", reading ); memset( reading, '
./prog1 | ./prog2
', 1025 ); } if( r_control < 0 ) perror( "read( )" ); close( fdin );

But, I think that fcntlcan be a better solution

但是,我认为这fcntl可能是一个更好的解决方案

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

回答by Johan

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

一个程序写入 stdout 的内容可以被另一个程序通过 stdin 读取。所以,简单地说,采用C语言,编写prog1使用打印的东西printf(),并prog2用阅读的东西scanf()。然后就跑

$ program_1 | program_2

回答by Preet Sangha

Here's a sample:

这是一个示例

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

}

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.
  1. popen()在子进程和父进程的管道之间建立关联的调用。
  2. fprintf()使用管道作为普通文件写入子进程的标准输入或从其标准输出读取的调用。
  3. pclose()关闭管道并导致子进程终止的调用。

回答by lfagundes

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:

首先,让程序 1 将字符串写入stdout(就像您希望它出现在屏幕上一样)。然后第二个程序应该从 中读取一个字符串stdin,就好像用户正在从键盘打字一样。然后你运行:

##代码##

回答by Anjana

This answer might be helpful for a future Googler.

这个答案可能对未来的 Google 员工有帮助。

##代码##

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

您可以在此处找到高级双向管道调用示例。