坚持在 C 中使用多个管道
Stuck on using multiple pipes in C
我正在编写一个程序,专门将 3 个程序链接在一起,等等 "ls | sort | wc"。
我查看了我在 google 上找到的关于多个管道的其他帖子,但我仍然无法弄清楚我做错了什么。坚持了一段时间。我相信我的程序在逻辑上是正确的,但由于某些原因它不正确 运行。我错过了什么?
pipe(pipe1);
pipe(pipe2);
pid = fork();
if(pid > 0){
close(pipe2[1]);
dup2(pipe2[0], 0);
execlp(argv[3], argv[3], NULL);
}
else if(pid == 0){
pid2 = fork();
if(pid2 == 0){
close(pipe1[0]);
dup2(pipe1[1], 1);
execlp(argv[1], argv[1], NULL);
}
else if(pid2 > 0){
close(pipe1[1]);
dup2(pipe1[0], 0);
close(pipe2[0]);
dup2(pipe2[1], 1);
execlp(argv[2], argv[2], NULL);
}
}
父case每次fork 3次,只在子case中执行命令。看看here
根据您的情况调整:
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char **argv) {
int pid;
int pipe1[2];
int pipe2[2];
// create pipe1
if (pipe(pipe1) == -1) {
perror("bad pipe1");
exit(1);
}
// fork (ps aux)
if ((pid = fork()) == -1) {
perror("bad fork1");
exit(1);
}
else if (pid == 0) {
// stdin --> ps --> pipe1
// input from stdin (already done), output to pipe1
dup2(pipe1[1], 1);
// close fds
close(pipe1[0]);
close(pipe1[1]);
execlp(argv[1], argv[1], NULL);
// exec didn't work, exit
perror("bad exec ps");
_exit(1);
}
// parent
// create pipe2
if (pipe(pipe2) == -1) {
perror("bad pipe2");
exit(1);
}
// fork (grep root)
if ((pid = fork()) == -1) {
perror("bad fork2");
exit(1);
}
else if (pid == 0) {
// pipe1 --> grep --> pipe2
// input from pipe1
dup2(pipe1[0], 0);
// output to pipe2
dup2(pipe2[1], 1);
// close fds
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execlp(argv[2], argv[2], NULL);
// exec didn't work, exit
perror("bad exec grep root");
_exit(1);
}
// parent
// close unused fds
close(pipe1[0]);
close(pipe1[1]);
// fork (grep sbin)
if ((pid = fork()) == -1) {
perror("bad fork3");
exit(1);
}
else if (pid == 0) {
// pipe2 --> grep --> stdout
// input from pipe2
dup2(pipe2[0], 0);
// output to stdout (already done). Close fds
close(pipe2[0]);
close(pipe2[1]);
execlp(argv[3], argv[3], NULL);
// exec didn't work, exit
perror("bad exec grep sbin");
_exit(1);
}
// parent
return 0;
}
我找到了另一个解决方案,父进程处理第一个命令,将其输出写入第一个管道并创建一个子进程将处理第二个命令并将其输出写入第二个管道,同时这个子进程将创建一个子进程-child 将处理第三个命令。
命令是:ls -l | grep "sthg"`| wc -l
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include <fcntl.h>
int main(){
int p[2],p1[2];
int x,y,z;
pipe(p);
x= fork();
if (x>0){//père or parent
close(p[0]);
dup2(p[1],1);
execlp("ls","ls","-l",NULL);
close(p[1]);
}
else{ // fils du père or child of parent
pipe(p1);
z=fork();
if(z>0){ //fils du père or child of parent
close(p[1]);
close(p1[0]);
dup2(p[0],0);
dup2(p1[1],1);
execlp("grep","grep","sthg",NULL);
close(p[0]);
close(p1[1]);
}
else{ //fils du fils or sub-child
close(p[0]);
close(p[1]);
close(p1[1]);
dup2(p1[0],0);
execlp("wc","wc","-l",NULL);
close(p1[0]);
}
}
return 0;
}
我正在编写一个程序,专门将 3 个程序链接在一起,等等 "ls | sort | wc"。
我查看了我在 google 上找到的关于多个管道的其他帖子,但我仍然无法弄清楚我做错了什么。坚持了一段时间。我相信我的程序在逻辑上是正确的,但由于某些原因它不正确 运行。我错过了什么?
pipe(pipe1);
pipe(pipe2);
pid = fork();
if(pid > 0){
close(pipe2[1]);
dup2(pipe2[0], 0);
execlp(argv[3], argv[3], NULL);
}
else if(pid == 0){
pid2 = fork();
if(pid2 == 0){
close(pipe1[0]);
dup2(pipe1[1], 1);
execlp(argv[1], argv[1], NULL);
}
else if(pid2 > 0){
close(pipe1[1]);
dup2(pipe1[0], 0);
close(pipe2[0]);
dup2(pipe2[1], 1);
execlp(argv[2], argv[2], NULL);
}
}
父case每次fork 3次,只在子case中执行命令。看看here
根据您的情况调整:
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char **argv) {
int pid;
int pipe1[2];
int pipe2[2];
// create pipe1
if (pipe(pipe1) == -1) {
perror("bad pipe1");
exit(1);
}
// fork (ps aux)
if ((pid = fork()) == -1) {
perror("bad fork1");
exit(1);
}
else if (pid == 0) {
// stdin --> ps --> pipe1
// input from stdin (already done), output to pipe1
dup2(pipe1[1], 1);
// close fds
close(pipe1[0]);
close(pipe1[1]);
execlp(argv[1], argv[1], NULL);
// exec didn't work, exit
perror("bad exec ps");
_exit(1);
}
// parent
// create pipe2
if (pipe(pipe2) == -1) {
perror("bad pipe2");
exit(1);
}
// fork (grep root)
if ((pid = fork()) == -1) {
perror("bad fork2");
exit(1);
}
else if (pid == 0) {
// pipe1 --> grep --> pipe2
// input from pipe1
dup2(pipe1[0], 0);
// output to pipe2
dup2(pipe2[1], 1);
// close fds
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execlp(argv[2], argv[2], NULL);
// exec didn't work, exit
perror("bad exec grep root");
_exit(1);
}
// parent
// close unused fds
close(pipe1[0]);
close(pipe1[1]);
// fork (grep sbin)
if ((pid = fork()) == -1) {
perror("bad fork3");
exit(1);
}
else if (pid == 0) {
// pipe2 --> grep --> stdout
// input from pipe2
dup2(pipe2[0], 0);
// output to stdout (already done). Close fds
close(pipe2[0]);
close(pipe2[1]);
execlp(argv[3], argv[3], NULL);
// exec didn't work, exit
perror("bad exec grep sbin");
_exit(1);
}
// parent
return 0;
}
我找到了另一个解决方案,父进程处理第一个命令,将其输出写入第一个管道并创建一个子进程将处理第二个命令并将其输出写入第二个管道,同时这个子进程将创建一个子进程-child 将处理第三个命令。
命令是:ls -l | grep "sthg"`| wc -l
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include <fcntl.h>
int main(){
int p[2],p1[2];
int x,y,z;
pipe(p);
x= fork();
if (x>0){//père or parent
close(p[0]);
dup2(p[1],1);
execlp("ls","ls","-l",NULL);
close(p[1]);
}
else{ // fils du père or child of parent
pipe(p1);
z=fork();
if(z>0){ //fils du père or child of parent
close(p[1]);
close(p1[0]);
dup2(p[0],0);
dup2(p1[1],1);
execlp("grep","grep","sthg",NULL);
close(p[0]);
close(p1[1]);
}
else{ //fils du fils or sub-child
close(p[0]);
close(p[1]);
close(p1[1]);
dup2(p1[0],0);
execlp("wc","wc","-l",NULL);
close(p1[0]);
}
}
return 0;
}