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

复刻Shell的C程序中execvp前子进程printf无输出问题咨询

问题分析:子进程中printf无输出但日志写入正常的原因及解决办法

我来帮你拆解这个问题——其实核心原因是stdio缓冲区的刷新机制和execvp的进程替换行为共同导致的,咱们一步步说:

  • 首先,printf("ABC")没有换行符,而stdout默认是行缓冲模式:只有当输出遇到换行符、缓冲区被填满,或者主动调用fflush(stdout)时,缓冲区里的内容才会真正输出到终端。你的"ABC"就一直留在缓冲区里没发出来。
  • 再看日志写入:你用fprintf写文件后调用了fclose(f),而fclose会自动刷新该文件的缓冲区,所以日志内容能正常写入tmp.log,这部分没问题。
  • 关键来了:当你调用execvp时,它会完全替换当前子进程的整个地址空间——包括stdio的缓冲区。这时候缓冲区里还没来得及输出的"ABC"就被直接丢弃了,自然看不到任何输出。

解决办法(二选一即可)

  1. 给printf加上换行符,触发行缓冲自动刷新:
printf("ABC\n");
  1. 主动刷新stdout缓冲区,强制输出内容:
printf("ABC");
fflush(stdout);

修改后的核心代码片段

else if(pid == 0){
    FILE *f;
    //open the file and append. Create if not there.
    f = fopen("tmp.log", "a+");
    if (f == NULL) { printf("Something is wrong");}
    struct tm *p;
    struct tm buf;
    char timestring[100];
    time_t ltime = time(NULL);
    if (NULL != (p=localtime_r(&ltime, &buf))){
        strftime(timestring, sizeof(timestring),"** %c: ", p);
        fprintf(f, "%s %s \n", timestring, user_input);
    }
    fclose(f);

    char* separator = " ";
    char* argv[64];
    int argc = 0;
    char* tmp;
    argv[argc] = strtok_r(user_input, separator, &tmp);
    while( argv[argc] != NULL){
        argc+=1;
        argv[argc] = strtok_r(NULL, separator, &tmp);
    }

    // 方案1:加换行符
    printf("ABC\n");
    // 方案2:主动刷新缓冲
    // printf("ABC");
    // fflush(stdout);

    execvp(argv[0],argv);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:03