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

如何在Shell脚本中周期性向后台C程序的stdin写入数据?

解决方案:实现周期性向C程序的stdin发送数据

你的核心问题是后台运行的C程序和脚本中的cat没有共享stdin流,导致数据无法传递。下面提供两种简单可行的实现方案,同时修正C代码中的潜在问题。


一、修正C代码中的问题

原代码里的fflush(stdin)属于标准未定义行为(fflush仅对输出流有效),且未处理read的错误/EOF情况,同时printf因为行缓冲可能无法实时输出。修改后的代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int FnReceiveCharacter(void)
{       
    unsigned char c = 0;
    ssize_t read_len = read(STDIN_FILENO, &c, 1);
    
    // 处理读取失败或EOF(比如管道关闭)
    if (read_len <= 0) {
        exit(EXIT_SUCCESS);
    }
    return c;
}

int main( )
{
    while(1) {
        printf("%c", FnReceiveCharacter());
        fflush(stdout); // 强制刷新输出缓冲,确保实时打印
    }
    return 0;
}

编译命令不变:cc filename.c -o a.out


二、方案1:使用管道(最简单)

直接将脚本中周期性输出的数据通过管道传递给C程序的stdin,无需后台运行C程序。修改后的shell脚本:

#!/bin/sh
clear
echo "running the shell command"

# 将while循环的输出直接作为a.out的输入
while true 
do
    sleep 2
    # 输出测试数据,$PPID可替换为你需要的内容
    echo "# check $PPID"
done | ./a.out

原理

管道|会将前一个命令(while循环)的stdout直接连接到后一个命令(./a.out)的stdin,数据会自动从循环传递到C程序。


三、方案2:使用命名管道(FIFO,适合多进程场景)

如果需要多个进程向C程序发送数据,或者C程序必须后台运行,可以用命名管道实现进程间通信:

#!/bin/sh
clear
echo "running the shell command"

# 创建命名管道(虚拟文件)
FIFO_PATH="./my_fifo"
mkfifo "$FIFO_PATH"

# 让C程序从命名管道读取数据,后台运行
./a.out < "$FIFO_PATH" &
A_OUT_PID=$!

# 周期性向命名管道写入数据
while true 
do
    sleep 2
    echo "# check $PPID" > "$FIFO_PATH"
done

# 脚本退出时清理资源(杀死C进程、删除管道)
trap "kill $A_OUT_PID; rm -f $FIFO_PATH" EXIT

原理

命名管道是一个持久化的虚拟文件,任何进程都可以向它写入数据,同时从它读取的进程会获取这些数据,完美解决不同进程间的stdin共享问题。


内容的提问来源于stack exchange,提问作者Aatif Shaikh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:40:22