有人可以向我解释为什么我的输出在ls命令中有重复. ls -l |的正常运行sort不会给我一个重复的输出所以可能是什么问题?
基本上我正在尝试从一个命令管道输出并将其输入另一个命令.该程序到目前为止工作,但输出显示重复数据.加上并解释为什么我需要在dup2之后关闭它真的很有帮助:)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
// function declarations
void executeLs(int data_pipe[]);
void executeSort(int data_pipe[]);
int main(){
int data_pipe[2]; // array storing the file descriptors
int childls_pid; // ls child process
int childSort_pid; // sort child process
int rc; // return vaue of the pipe
int child_status1;
int child_status2;
rc = pipe(data_pipe);
if(rc == -1){
perror("pipe");
exit(1);
}
childls_pid = fork();
childSort_pid = fork();
// Ls Child process
switch(childls_pid) {
case -1:
perror("fork childLs Error");
exit(1);
case 0:
// inside of child process
executeLs(data_pipe);
exit(0);
default:
break;
}
// Sort child process
switch(childSort_pid) {
case -1:
perror("fork childSort Error");
exit(1);
case 0:
executeSort(data_pipe);
exit(0);
default:
wait(&child_status2);
}
return 0;
}
void executeLs(int data_pipe[]){
// Closes the read file descriptor
close(data_pipe[0]);
dup2(data_pipe[1], STDOUT_FILENO);
// confused as to why this is necessary
close(data_pipe[1]);
execlp("ls", "ls", "-1", NULL);
}
void executeSort(int data_pipe[]){
// close the write file descriptor
close(data_pipe[1]);
dup2(data_pipe[0], STDIN_FILENO);
close(data_pipe[0]);
execlp("sort","sort", NULL);
}
最佳答案 原因是你要求比你想要的更多的流程.当你这样做时:
childls_pid = fork();
childSort_pid = fork();
你在原始父进程和第一个fork()创建的进程中执行第二个fork().所以你现在有了以下进程树:
parent
childls
childSort
childSort
在childls和childls-> childSort中,childls_pid为0,因此它们都执行运行executeLs()的case 0:子句.
您需要将第二个fork移动到仅在原始父级中运行的代码中.您可以在第一个switch语句之后将其移动到.
您需要关闭管道FD的原因是因为管道并非真正关闭,直到所有打开它的进程关闭它.如果子进程的管道的写入结束打开,那么将阻止它在管道上读取EOF.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
// function declarations
void executeLs(int data_pipe[]);
void executeSort(int data_pipe[]);
int main(){
int data_pipe[2]; // array storing the file descriptors
int childls_pid; // ls child process
int childSort_pid; // sort child process
int rc; // return vaue of the pipe
int child_status1;
int child_status2;
rc = pipe(data_pipe);
if(rc == -1){
perror("pipe");
exit(1);
}
childls_pid = fork();
// Ls Child process
switch(childls_pid) {
case -1:
perror("fork childLs Error");
exit(1);
case 0:
// inside of child process
executeLs(data_pipe);
exit(0);
default:
break;
}
childSort_pid = fork();
// Sort child process
switch(childSort_pid) {
case -1:
perror("fork childSort Error");
exit(1);
case 0:
executeSort(data_pipe);
exit(0);
default:
wait(&child_status2);
}
return 0;
}
void executeLs(int data_pipe[]){
// Closes the read file descriptor
close(data_pipe[0]);
dup2(data_pipe[1], STDOUT_FILENO);
// confused as to why this is necessary
close(data_pipe[1]);
execlp("ls", "ls", "-1", NULL);
}
void executeSort(int data_pipe[]){
// close the write file descriptor
close(data_pipe[1]);
dup2(data_pipe[0], STDIN_FILENO);
close(data_pipe[0]);
execlp("sort","sort", NULL);
}