使用execlp调用read命令读取标准输入失败的修复方法
问题分析与修复方案
原代码核心问题
read命令误用:read是Shell内置命令,并非独立可执行程序,execlp无法直接调用它。即便能调用,它仅会将stdin输入存入Shell变量,不会将内容输出到stdout,管道中不会有数据传递给父进程。- 重定向逻辑颠倒:父进程将自身stdin重定向到管道读端,导致无法接收终端输入;子进程将stdout重定向到管道写端,但
read无输出,管道始终为空。 - 缺失错误处理:
execlp执行失败后无后续处理,子进程直接退出,父进程会因等待管道数据而卡住。
修复方案
根据你的需求(从stdin读取输入并存储处理),提供两种实现方式:
方案一:直接在主进程读取stdin(无需父子进程)
如果不需要多进程拆分任务,直接读取stdin是最简洁的方式:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #define BUFFER_SIZE 1024 int main() { char buffer[BUFFER_SIZE]; ssize_t bytes_read; // 循环读取stdin输入,直到EOF或出错 while ((bytes_read = read(STDIN_FILENO, buffer, BUFFER_SIZE - 1)) > 0) { buffer[bytes_read] = '\0'; // 确保字符串终止 // 此处可添加存储/处理逻辑,比如写入文件、解析内容等 printf("已读取内容:%s", buffer); } if (bytes_read == -1) { perror("读取输入失败"); exit(EXIT_FAILURE); } return 0; }
方案二:用父子进程+管道拆分读写任务
如果需要用多进程分离读取和处理逻辑,调整管道流向,让子进程读stdin并写入管道,父进程从管道读取内容:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <err.h> #include <sys/wait.h> #define BUFFER_SIZE 1024 int main() { int pipe_fd[2]; if (pipe(pipe_fd) == -1) { err(1, "创建管道失败"); } pid_t pid = fork(); if (pid < 0) { err(1, "创建子进程失败"); } if (pid == 0) { // 子进程:读取stdin,写入管道 close(pipe_fd[0]); // 关闭管道读端 char buffer[BUFFER_SIZE]; ssize_t bytes_read; while ((bytes_read = read(STDIN_FILENO, buffer, BUFFER_SIZE)) > 0) { if (write(pipe_fd[1], buffer, bytes_read) == -1) { err(1, "写入管道失败"); } } close(pipe_fd[1]); // 写完后关闭写端,触发父进程EOF exit(EXIT_SUCCESS); } else { // 父进程:从管道读取内容,存储处理 close(pipe_fd[1]); // 关闭管道写端 char buffer[BUFFER_SIZE]; ssize_t bytes_read; printf("父进程开始处理输入:\n"); while ((bytes_read = read(pipe_fd[0], buffer, BUFFER_SIZE)) > 0) { buffer[bytes_read] = '\0'; printf("处理内容:%s", buffer); // 此处可添加存储逻辑,比如写入文件、存入内存缓冲区等 } if (bytes_read == -1) { err(1, "读取管道失败"); } close(pipe_fd[0]); wait(NULL); // 等待子进程结束 } return 0; }
内容的提问来源于stack exchange,提问作者user17588651
相关产品推荐
相关产品推荐

