我在做标题中所说的事情时遇到了很大的麻烦。
基本上,我想要一个程序,例如broadcast.c,它接受用户的输入,然后将该输入发送到两个进程的输入。
因此,如果要运行以下命令:
./broadcast prog1 prog2
它将阻止等待用户的输入,然后将该输入发送到prog1和prog2。
现在,我想使用管道,问题是,我不知道我是否必须使用1个管道或2个管道。
广播
#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);
}
我知道这行不通,而且可能会搞砸,所以如果你们可以帮助我,那将是很好的。
现在,我只是想在执行此操作:
./broadcast prog1 prog2
用户输入:您好
输出为:
prog1说:您好!
prog2说:您好!
基本上prog1和prog2只是在fd 0上使用read进行打印。
最佳答案
我想要一个程序,例如broadcast.c,它接受用户的输入,然后将该输入发送到两个进程的输入。因此,如果要运行此命令:./broadcast prog1 prog2
您可以使用broadcast
实现bash
命令:
$ tee >/dev/null >(prog1) >(prog2)
tee
从stdin读取并将其发送到prog1
和prog2
。 tee
默认情况下将stdin复制到stdout,因此使用>/dev/null
禁止显示它。还有来自
pee
的moreutils
package命令:$ pee prog1 prog2
它正是您想要的。它使用
popen()
运行子进程。实现非常简单,这是完整的源代码(来自pee.c
的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));
}