c - fork()子执行命令奇怪地输出
问题描述
我正在尝试做 ls -la | 厕所
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
int main(int argc, char **argv)
{
int pipes=3;
char *ls[] = {"ls","-la",NULL};
char *wc[] = {"wc",NULL};
char *base64[] = {"base64","-w0",NULL};
//char **commands[] = {ls,wc,base64};
int fds[pipes][2];
for(int i=0;i<pipes;i++)
{
int err = pipe(fds[i]);
if(err == -1)
{
perror("Pipe failed.\n");
}
}
int status;
pid_t childPid;
//Child 1.
if((childPid = fork()) == 0)
{
dup2(fds[0][1],1);
for(int i=0;i<pipes;i++)
{
close(fds[i][0]);
close(fds[i][1]);
}
execvp(ls[0],ls);
exit(0);
}
else if(childPid == -1)
{
perror("Child 1 failed.\n");
}
// Second child.
if((childPid = fork()) == 0)
{
dup2(fds[0][0],0);
for(int i=0;i<pipes;i++)
{
close(fds[i][0]);
close(fds[i][1]);
}
execvp(wc[0],wc);
}
else if(childPid == -1)
{
perror("Child 2 failed.\n");
}
for(int i=0;i<pipes;i++)
{
close(fds[i][0]);
close(fds[i][1]);
}
waitpid(childPid,&status,WUNTRACED|WNOHANG);
return 0;
}
出乎意料:
root@danial#gcc -o pip pip.c
root@danial#./pip
10 83 436
我得到的输出:
root@danial#./pip
根@danial# 10 83 436
光标停留在这里,直到我按下回车键。
我尝试在没有管道的情况下这样做,只是编写了一个简单的程序:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
int main(int argc, char **argv)
{
if(fork() == 0)
{
execlp("ls","ls","-la",NULL);
exit(0);
}
return 0;
}
同样的事情发生了:
root@danial#./test
根@danial#total 84
drwxr-xr-x 3 根根 4096 Mar 30 06:49 。
drwxr-xr-x 9 根根 4096 Mar 29 09:33 ..
-rwxr-xr-x 1 根 16960 Mar 30 06:49 pip
-rw-r--r-- 1 根根 1310 Mar 30 06:48 pip.c
解决方案
问题是这个
waitpid(childPid,&status,WUNTRACED|WNOHANG);
WNOHANG
你告诉轮询状态,waitpid
然后立即返回而不实际等待。
当waitpid
调用返回时,您退出父进程,使您的两个子进程成为孤立的。
当父进程退出时会发生什么是它的父进程(shell)接管并打印提示。然后你的子进程打印他们的输出。您按下以“清除”输出的Enter键只是 shell 的空输入。
您需要等待您的两个子进程。
推荐阅读
- reactjs - 当我点击任何手风琴时,每个手风琴都会打开:react js
- javascript - 根据 URL / BootstrapVue 填写输入字段
- java - Android:setPivotx() 后 x 位置未更新
- spring - 为什么字符串没有通过 Model.addObject 添加到属性中?
- java - 如何在 selenium(java) 中选择多个复选框?
- android - 在活动和应用程序类中使用伴生对象是一种好方法吗?
- html - 发送带有图像背景的电子邮件
- python - 我如何解决 TypeError:'function' 对象不可下标
- python-3.x - 你能帮忙'tf.vectorize_map'形状输出错误吗
- python - 无法将合并的 Dask 数据帧转换为 pandas 数据帧 - 出现错误“作为索引器提供的不可对齐布尔系列”