有人可以向我解释为什么我的输出中有来自 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);
}
最佳答案
原因是您 fork 的进程比您预期的要多。当你这样做时:
childls_pid = fork();
childSort_pid = fork();
您正在原始父进程和第一个 fork()
创建的进程中执行第二个 fork()
。所以你现在有以下进程树:
parent
childls
childSort
childSort
在childls
和childls->childSort
中,childls_pid
都是0,所以它们都执行case 0:
运行 executeLs()
的子句。
您需要将第二个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);
}
关于c - 管道输出的重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33814160/