【发布时间】:2011-12-27 15:58:55
【问题描述】:
基本上我想在 C 中(并且没有缓冲)与这个 bash 脚本一样:
#!/bin/sh
cat ./fifo_in | myprogram > ./fifo_out
换句话说,我想执行“myprogram”并将其标准输入和标准输出重定向到之前创建的两个管道。
另一个程序正在将数据输入 fifo_in 并从 fifo_out 中读出。
当然很容易从./fifo_in 读取,将其缓冲在父程序中并写入myprogram 的标准输入(对于stdout 和./fifo_out 反向),但我认为可能有一种方法可以让“myprogram”直接从/向fifos读取/写入,而不在父进程中缓冲。
编辑:
Eugen 的答案似乎是正确的,但我无法让它发挥作用。
我在 C 端使用这个函数,这对我来说似乎是正确的:
pid_t execpipes(const char *wd, const char *command, const char *pipename)
{
char pipename_in[FALK_NAMESIZE];
char pipename_out[FALK_NAMESIZE];
strcpy(pipename_in, FALKPATH);
strcat(pipename_in, "/");
strcat(pipename_in, FALK_FIFO_PATH);
strcat(pipename_in, "/");
strncat(pipename_in, pipename, FALK_NAMESIZE-2);
strcpy(pipename_out, pipename_in);
strcat(pipename_out, "R");
pid_t pid;
pid = fork();
if (pid < 0)
{ //Error occured
perror("fork");
exit(1);
}
if (pid == 0)
{
chdir(wd);
d("execpipes: pipename_in=\"%s\"\n", pipename_in);
d(" pipename_out=\"%s\"\n", pipename_out);
freopen(pipename_in,"r",stdin);
freopen(pipename_out,"w",stdout);
d("execpipes: command=\"%s\"\n", command);
execl("/bin/sh", "sh", "-c", command, (char *)NULL); // using execv is probably faster
// Should never get here
perror("execl");
exit(1);
}
return pid;
}
我从 PHP 脚本读取和写入管道(仅发布相关部分):
$pipe_in = fopen($fp.$pipename, "w");
$DEBUG .= "Write to pipe_in\n";
$ret = fwrite($pipe_in, $in);
$pipe_out = fopen($fp.$pipename.'R', "r");
$DEBUG .= "Read from pipe_out\n";
$atext = fread($pipe_out, 200000); // Program hangs here
程序正确启动,通过$pipe_in 正确接收输入,正确处理数据并且(因为它运行了好几个月)我认为它正确地将数据输出到标准输出,但是当我尝试从$pipe_out,挂了。我知道管道本身设置正确,因为如果我不打开$pipe_out,程序不会得到任何输入——这是有道理的,因为$pipe_out 没有阅读器,因此管道不完整。所以我可以打开$pipe_out,但我不能从中读取任何内容,这很奇怪。
编辑2:
程序现在可以运行了,谢谢大家 - 出于某种原因,必须先关闭第一个管道,然后才能从第二个管道读取:
$pipe_in = fopen($fp.$pipename, "w");
$pipe_out = fopen($fp.$pipename.'R', "r");
$DEBUG .= "Write to pipe_in\n";
$ret = fwrite($pipe_in, $in);
fclose($pipe_in);
$DEBUG .= "Read from pipe_out\n";
$atext = fread($pipe_out, 200000);
fclose($pipe_out);
unlink($fp.$pipename);
unlink($fp.$pipename.'R');
【问题讨论】:
-
您是在为
myprogram或其他“调用”myprogram的程序编写源代码吗? -
有什么理由滥用
cat?为什么不使用:myprogram < ./fifo_in > ./fifo_out? -
没有理由使用 cat,bash 脚本只是为了阐明 C 程序应该做什么。