提问人:Jonathan Chiou 提问时间:2/16/2014 最后编辑:Jonathan Chiou 更新时间:2/17/2014 访问量:759
管道问题(管道破裂)
Piping problems (Broken pipe)
问:
给定以下格式的命令:
cat < inputfile.txt | tee outputfile.txt
我正在尝试让输入文件.txt写入管道,然后从管道中读取输出文件.txt,并且我编写了以下功能来执行此操作:
void piperead(char** input, int* fd, int start) {
dup2(fd[0], 0);
close(fd[1]);
execl("usr/bin/tee", "usr/bin/tee", input[start + 1], NULL);
}
void pipewrite(char** input, int* fd, int start, int end) {
dup2(fd[1], 1);
close(fd[0]);
execl("usr/bin/cat", "usr/bin/tee", input[start + 2], NULL);
}
void dopiping(char** input, int start, int end) {
int fd[2];
if (pipe(fd) == -1) {
cout << "Error: Pipe failed." << endl;
exit(1);
}
int pid = fork();
switch(pid = fork()) {
case 0:
piperead(input, fd, start, end);
default:
pipewrite(input, fd, end + 1);
case -1:
exit(1);
}
}
我已将命令转换为c_strings数组(我们将其称为 cmdarray),然后调用 dopiping(cmdarray, 0, 3)。程序到达生产线的那一刻:
dup2(fd[1], 1)
程序终止,因为程序收到了 SIGPIPE。为什么我的管道坏了,我该如何解决?
答:
1赞
Beano
2/17/2014
#1
所以从逻辑上看
- SIGPIPE 被传送到一个进程,该进程对封闭的管道/套筒执行 write()。
- 因此,您创建的管道的读取侧必须已关闭。
- 执行
fd[0]
dup2()
- 因此,子进程似乎正在退出。
- 我猜要么是失败的 - 你应该尝试指定“/usr/bin/tee”(完整路径而不是相对路径)
execl()
- 或 your is failed - 需要确保指向表示有效文件路径的 null 终止字符串。
tee
input[start+1]
评论
"usr/bin/cat"
"/usr/bin/cat"
exec
fork
execl(3)
的手册页,你会看到它 “用一个新的进程映像替换了当前的进程映像”, 并且该函数没有返回。你通常调用fork(2)
来创建一个新的进程来执行调用,这样你的主进程就可以继续运行。exec