![](/img/trans.png)
[英]c program with pipes to excecute “ps aux | grep firefox | tee processes.txt”
[英]Program to execute ps aux | grep root | wc -l using pipes in C
我必須編寫一個顯示與我寫ps aux | grep root | wc -l
相同輸出的程序ps aux | grep root | wc -l
ps aux | grep root | wc -l
終端中的ps aux | grep root | wc -l
。 在此網絡中搜索答案但未找到任何內容,並嘗試從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:請報告此錯誤
有人可以給我解釋一下為什么該程序不能正常工作嗎? 因為我確定不是因為我必須報告該錯誤。
分叉程序不是太復雜,但是需要非常嚴格的編碼實踐,因為如果出錯,則很難調試。 在這里,我必須首先讓僅父級運行(僅ps
),然后讓父級和子級( ps | wc
)運行。 在那一刻,我注意到,在操作child_grandchild_fd
是在交錯操作入賬金額parent_child_fd
,但它給了預期的效果。
但是在取消注釋孫子部分的那一刻,我注意到您的代碼在fork之前關閉了child_grandchild_fd
,因此當您嘗試在孫子中使用它時,您只會將已經關閉的句柄進行child_grandchild_fd
。 因此,孫子在使用管道內容之前從封閉的句柄讀取並退出。
修復很簡單:首先進行分叉,然后在分支中管理管道:
...
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);
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.