gpt4 book ai didi

c - 执行 ps aux | 的程序grep 根 | wc -l 在 C 中使用管道

转载 作者:行者123 更新时间:2023-11-30 16:36:59 26 4
gpt4 key购买 nike

我必须编写一个程序,该程序显示与我编写 ps aux | grep root | wc -l 相同的输出在终端中。在这个网络上搜索答案但没有找到任何东西后,并试图理解this program来自 GitHub(当我运行它时没有正确完成),这是我的卑微尝试:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <string.h>

// Program to execute ps aux | grep root | wc -l

int main(int argc, char const *argv[]) {

int parent_child_fd[2];
pid_t child,grandchild;

if (pipe(parent_child_fd) == -1) {
perror("Error creating parent_child_fd");
return EXIT_FAILURE;
}
if ((child = fork()) == -1) {
perror("Error forking child");
return EXIT_FAILURE;
}else if(child == 0){
int child_grandchild_fd[2];

if (pipe(child_grandchild_fd) == -1) {
perror("Error creating child_grandchild_fd");
exit(EXIT_FAILURE);
}

close(parent_child_fd[1]);
close(child_grandchild_fd[0]);

dup2(parent_child_fd[0],0);
close(parent_child_fd[0]);
dup2(child_grandchild_fd[1],1);
close(child_grandchild_fd[1]);

if ((grandchild = fork()) == -1) {
perror("Error forking child");
exit(EXIT_FAILURE);
}else if(grandchild == 0){
close(child_grandchild_fd[1]);
dup2(child_grandchild_fd[0],0);
execlp("/usr/bin/wc","/usr/bin/wc","-l",(char*)NULL);

perror("Grandchild failed executing wc");
exit(EXIT_FAILURE);
}

execlp("/bin/grep","/bin/grep","root",(char*)NULL);
perror("Child failed executing grep");
exit(EXIT_FAILURE);
}

close(parent_child_fd[0]);
dup2(parent_child_fd[1],1);
close(parent_child_fd[1]);

execlp("/bin/ps","/bin/ps","aux", (char*)NULL);
perror("Parent failed executing ps");

return -1;
}

但是,我总是得到相同的输出:

信号 17 (CHLD) 被 ps (3.3.12) 捕获。/bin/ps:ps/display.c:66:请报告此错误

有人能给我解释一下为什么这个程序不能正常工作吗?因为我确信这不是因为我必须报告的错误。

最佳答案

fork 程序并不过分复杂,但需要非常严格的编码实践,因为当出现错误时,调试起来会更加困难。在这里,我必须首先仅让父级运行(仅 ps),然后是父级和子级(ps | wc)。当时我注意到对 child_grandchild_fd 的操作与对 parent_child_fd 的操作交错,但它给出了预期的结果。

但是在取消注释孙子部分时,我注意到您的代码正在关闭 child_grandchild_fd 在 fork 之前,因此当您尝试在孙子中使用它时,您只复制已经关闭的句柄。因此,孙子会从关闭的句柄中读取内容,并在使用管道的内容之前退出。

修复很简单:首先只需 fork ,然后管理分支中的管道:

...
if (pipe(child_grandchild_fd) == -1) {
perror("Error creating child_grandchild_fd");
exit(EXIT_FAILURE);
}

close(parent_child_fd[1]);

dup2(parent_child_fd[0],0);
close(parent_child_fd[0]);

if ((grandchild = fork()) == -1) {
perror("Error forking child");
exit(EXIT_FAILURE);
}else if(grandchild == 0){
close(child_grandchild_fd[1]);
dup2(child_grandchild_fd[0],0);
execlp("/usr/bin/wc","/usr/bin/wc","-l",(char*)NULL);

perror("Grandchild failed executing wc");
exit(EXIT_FAILURE);
}
dup2(child_grandchild_fd[1],1); // moved after the fork
close(child_grandchild_fd[0]);
close(child_grandchild_fd[1]);
execlp("/usr/bin/grep","/usr/bin/grep","root",(char*)NULL);
perror("Child failed executing grep");
exit(EXIT_FAILURE);
...

关于c - 执行 ps aux | 的程序grep 根 | wc -l 在 C 中使用管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48179615/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com