如何为execl启动的后台程序提供输入?Linux C程序调用问题
问题描述
在Linux环境下编写C程序,需调用可执行文件A。A运行时会提示按下任意键才启动,需要在自己的C程序中调用A并自动传入按键输入,让A正常运行一段时间后终止。
A的核心逻辑如下:
// 读取配置文件 fprintf(stderr, "\n---------Hit Any Key To Start"); getc(stdin); // 后续业务逻辑
我编写的调用代码如下:
pid_t pid = fork(); int fd[2]; int read_end = 0; int write_end = 1; if(-1 == pipe(fd)) { // 错误处理 } if(-1 == pid) { // 错误处理 }else if (0 == pid) { close(fd[write_end]); dup2(fd[read_end], STDIN_FILENO); // 使用execl执行A,日志显示A卡在等待输入的步骤 execl(A ...) }else { close(fd[read_end]); char key = 'y'; // 担心A没收到输入,写了两次,但没用 write(fd[write_end], &key, sizeof(key)); sleep(10); write(fd[write_end], &key, sizeof(key)); // 让A运行一段时间后终止 sleep(75); kill(pid, SIGTERM); // 其他处理 // ... }
预期效果:通过bash脚本启动我的程序后,程序能自动让A启动并运行一段时间后退出。
解决方案
问题核心在于两个细节:
- 管道写端未关闭:父进程写完输入字符后没有关闭管道写端,导致子进程的
getc(stdin)会一直等待更多输入(内核认为写端仍存在,可能还有数据传入)。 - 输入匹配问题:部分场景下程序会隐含期望换行符(模拟用户按回车的操作),仅写入单个字符可能不符合预期,但优先级低于管道未关闭的问题。
修改后的父进程代码:
}else { close(fd[read_end]); char key = '\n'; // 用换行符更贴近用户手动按回车的场景,也可保留'y' write(fd[write_end], &key, sizeof(key)); close(fd[write_end]); // 写完立即关闭写端,让子进程的getc读取到字符后返回 sleep(75); kill(pid, SIGTERM); // 其他处理 // ... }
补充说明:当stdin被重定向到管道后,终端的标准行缓冲/规范模式会被取消,变为无缓冲模式,只要管道写端关闭,getc就会在读取到传入字符后立即返回,不会持续阻塞。
内容的提问来源于stack exchange,提问作者platanifolia
相关产品推荐
相关产品推荐

