标准输出重定向一个进程的两个进程 [英] Redirect stdout of one process to two processes

查看:112
本文介绍了标准输出重定向一个进程的两个进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

林有在做什么,我在题曰大烦恼。
基本上,我希望有一个程序,说broadcast.c,从用户接受输入,然后发送该输入到两个过程的输入。
因此,如果将运行这个命令:
./broadcast PROG1 PROG2

这将阻止正在等待来自用户的输入,然后发送该输入PROG1和PROG2

现在,我想使用管道,事情是,我不知道如果我必须使用1管或2管。

broadcast.c

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;    INT主(INT ARGC,CHAR *的argv []){
        INT FDS1 [2],FDS2 [2];
        炭缓冲器[120];
        管(FDS1);
        管(FDS2);        如果(叉()== 0){
            关闭(0);
            DUP(FDS1 [0]);
            关闭(FDS1 [0]);
            关闭(FDS1 [1]);
            EXECL(ARGV [1],ARGV [1],NULL);
        }        如果(叉()== 0){
            关闭(0);
            DUP(FDS2 [0]);
            关闭(FDS2 [0]);
            关闭(FDS2 [1]);
            execl的(的argv [2],的argv [2],NULL);
        }        而(读(0,缓冲液,120)!= 0){
            的printf(利多:%S \\ n,缓冲区);
            写(FDS1 [0],缓冲液,120);
            写(FDS2 [0],缓冲液,120);
        }        关闭(1);
        DUP(FDS1 [1]);
        DUP(FDS2 [1]);
        出口(0);
    }

我知道这并不工作,它可能会混乱,所以如果你们能帮助我走出这将是巨大的。

现在我只是想,当我做的:
./broadcast PROG1 PROG2
用户输入:您好

的输出是:
PROG1说:您好!
PROG2说:您好!

基本上PROG1和PROG2只是打印使用阅读FD 0。


解决方案

  

我希望有一个程序,说broadcast.c,从用户接受输入,然后发送该输入到两个过程的输入。因此,如果将运行此命令: ./广播PROG1 PROG2


您可以实施广播使用命令庆典

  $ T恤>的/ dev / null的>(PROG1)GT;(PROG2)

T恤从标准输入读取,并将其发送到 PROG1 PROG2 T恤默认重复标准输入,因此到stdout >的/ dev / null的用于燮preSS它。

还有 撒尿 通过 moreutils 命令:

  $撒尿PROG1 PROG2

据不正是你想要的。它采用的popen()运行子进程。实现很简单,这里的整个源代码code( pee.c 的git://git.kitenet.net/moreutils

 的#include<&stdlib.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / wait.h>/ *采用GPL许可协议
 *版权所有(C)Miek Gieben,2006年
 * // *像三通(1),但是如果使用连接到其他程序
 *管道_and_输出到标准输出
 * /INT
close_pipes(FILE ** P,为size_t I)
{
    INT RET = EXIT_SUCCESS;
    为size_t焦耳;
    为(J = 0; J< I; J ++){
        INT R = pclose函数(P [J]);
        如果(WIFEXITED(R))的
            保留| = WEXITSTATUS(R);
        其他
            保留| = 1;
    }
    返回RET;
}INT
主(INT ARGC,字符** argv的){
    为size_t I,R;
    文件**管道;
    烧焦的buf [BUFSIZ];    管道= malloc的(((argc个 - 1)* sizeof的*管道));
    如果(!管道)
        出口(EXIT_FAILURE);    对于(i = 1; I< ARGC,我++){
        管[I - 1] =的popen(argv的[I]中,W);
        如果(管道[我 - 1]!){
            fprintf中(标准错误,无法打开管道改为%s \\'\\ n,argv的[I]);
            close_pipes(管道,的argc);            出口(EXIT_FAILURE);
        }
    }
    argc--;    而(的feof(标准输入)及!&安培;!(FERROR(标准输入))){
        R = FREAD(BUF,sizeof的(炭),BUFSIZ,标准输入);
        对于(i = 0; I< ARGC,我++){
            如果(FWRITE(BUF,sizeof的(炭),R,管道由[i])!= R){
                fprintf中(标准错误,写错误'%s的\\'\\ n,argv的[I + 1]);
                close_pipes(管道,的argc);
                出口(EXIT_FAILURE);
            }
        }
    }
    出口(close_pipes(管道,的argc));
}

Im having big troubles in doing what i said in title. Basically, i want a program, say broadcast.c, that accepts input from the user and then sends that input to the input of two processes. So if would run this command: ./broadcast prog1 prog2

It would block awaiting the input from the user and then sending that input to prog1 and prog2.

Now, i want to use pipes, thing is, i dont know if i have to use 1 pipe or 2 pipes.

broadcast.c

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

    int main(int argc, char* argv[]) {
        int fds1[2], fds2[2];
        char buffer[120];
        pipe(fds1);
        pipe(fds2);

        if (fork() == 0) {
            close(0);
            dup(fds1[0]);
            close(fds1[0]);
            close(fds1[1]);
            execl(argv[1], argv[1], NULL);
        }

        if (fork() == 0) {
            close(0);
            dup(fds2[0]);
            close(fds2[0]);
            close(fds2[1]);
            execl(argv[2], argv[2], NULL);
        }

        while(read(0, buffer, 120) != 0) {
            printf("lido: %s\n", buffer);
            write(fds1[0],buffer,120);
            write(fds2[0],buffer,120);
        }

        close(1);
        dup(fds1[1]);
        dup(fds2[1]);
        exit(0);
    }

I know this doesnt work and it may be messed up, so if you guys could help me out that would be great.

For now i just want that when i do: ./broadcast prog1 prog2 The user enters: Hello

The output is: prog1 says: Hello! prog2 says: Hello!

Basically prog1 and prog2 are just print using read on fd 0.

解决方案

i want a program, say broadcast.c, that accepts input from the user and then sends that input to the input of two processes. So if would run this command: ./broadcast prog1 prog2

You could implement broadcast command using bash:

$ tee >/dev/null >(prog1) >(prog2)

tee reads from stdin and sends it to prog1 and prog2. tee by default duplicates stdin to stdout therefore >/dev/null is used to suppress it.

There is also pee command from moreutils package:

$ pee prog1 prog2

It does exactly what you want. It uses popen() to run child processes. The implementation is very simple, here's the whole source code (pee.c from git://git.kitenet.net/moreutils):

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

/* Licensed under the GPL
 * Copyright (c) Miek Gieben, 2006
 */

/* like tee(1), but then connect to other programs using
 * pipes _and_ output to standard output
 */

int
close_pipes(FILE **p, size_t i) 
{
    int ret=EXIT_SUCCESS;
    size_t j;
    for (j = 0; j < i; j++) {
        int r = pclose(p[j]);
        if (WIFEXITED(r))
            ret |= WEXITSTATUS(r);
        else
            ret |= 1;
    }
    return ret;
}

int
main(int argc, char **argv) {
    size_t i, r;
    FILE **pipes;
    char buf[BUFSIZ];

    pipes = malloc(((argc - 1) * sizeof *pipes));
    if (!pipes) 
        exit(EXIT_FAILURE);

    for (i = 1; i < argc; i++) {
        pipes[i - 1] = popen(argv[i], "w");
        if (!pipes[i - 1]) {
            fprintf(stderr, "Can not open pipe to '%s\'\n", argv[i]);
            close_pipes(pipes, argc);

            exit(EXIT_FAILURE);
        }
    }
    argc--;

    while(!feof(stdin) && (!ferror(stdin))) {
        r = fread(buf, sizeof(char), BUFSIZ, stdin);
        for(i = 0; i < argc; i++) {
            if (fwrite(buf, sizeof(char), r, pipes[i]) != r) {
                fprintf(stderr, "Write error to `%s\'\n", argv[i + 1]);
                close_pipes(pipes, argc);
                exit(EXIT_FAILURE);
            }
        }
    }
    exit(close_pipes(pipes, argc));
}

这篇关于标准输出重定向一个进程的两个进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆