You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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启动并运行一段时间后退出。

解决方案

问题核心在于两个细节:

  1. 管道写端未关闭:父进程写完输入字符后没有关闭管道写端,导致子进程的getc(stdin)会一直等待更多输入(内核认为写端仍存在,可能还有数据传入)。
  2. 输入匹配问题:部分场景下程序会隐含期望换行符(模拟用户按回车的操作),仅写入单个字符可能不符合预期,但优先级低于管道未关闭的问题。

修改后的父进程代码:

}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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:52:24