c - 带有 fork 和 dup2 的管道命令
问题描述
我编写了以下代码以通过管道传输两个命令:
#include <stdlib.h>
#include <unistd.h>
char *program_1[3] = {"/bin/cat", "/dev/random", NULL};
char *program_2[2] = {"/bin/ls", NULL};
char *program_3[2] = {"/usr/bin/sort", NULL};
int main(void)
{
int fd[2];
int pid;
pipe(fd);
if ((pid = fork()) == 0) //Child process
{
dup2(fd[1], STDOUT_FILENO);
close(fd[0]);
execve(program_3[0], program_3, NULL);
}
else if (pid > 0) //Parent process
{
dup2(fd[0], STDIN_FILENO);
close(fd[1]);
execve(program_2[0], program_2, NULL);
}
return (EXIT_SUCCESS);
}
每对 program_x / program_y 其中 x != y 工作正常,除了这一对。当我通过管道将 sort 输入 ls 时,ls 会在 stdout 上很好地打印其输出,但随后 sort 会抛出此错误:sort: Input/output error
.
当我输入sort | ls
bash 时,它会打印 ls 结果作为我的程序,然后等待输入。
我做错了吗?
编辑:我正在尝试重新实现 shell 的行为
解决方案
问题是,当ls
完成时,父进程将退出,这将关闭管道的读取端,这将导致错误传播到管道的写入端,被检测到sort
并写入错误消息。
它不会在 shell 中发生是因为 shell 处理管道的方式与您的简单示例程序不同,并且它保持管道的右侧打开并运行(可能在后台),直到您将EOF
( Ctrl-D) 传递给sort
程序。
推荐阅读
- c++ - 按非惰性 lambda 表达式/投影排序
- angular - 如何让这个自定义验证器工作?
- avfoundation - 是否可以为使用 AVMutableComposition 和 AVAssetExportSession 创建的视频文件设置输出音频采样率?
- python - 在 pandas 中用 NaN 替换某些字符串
- spring - org.springframework.context.ApplicationContextException:无法启动 bean 'org.springframework.kafka.config.internalKafkaListenerEndpointRegistry
- ruby-on-rails - Rake db:migrate 不适用于 pg Gem。如何修复错误?
- tfs - “Newtonsoft.Json”已经在 TFS 构建上为“Microsoft.CSharp”定义了一个依赖项
- c++ - 在 Windows 上使用 CUDA、TBB、MKL、VTK 构建 OpenCV
- android - 异步操作在 AsyncTask 中运行在哪里?
- python - 如何在 Flask 中调用另一个视图