复刻Shell的C程序中execvp前子进程printf无输出问题咨询
问题分析:子进程中printf无输出但日志写入正常的原因及解决办法
我来帮你拆解这个问题——其实核心原因是stdio缓冲区的刷新机制和execvp的进程替换行为共同导致的,咱们一步步说:
- 首先,
printf("ABC")没有换行符,而stdout默认是行缓冲模式:只有当输出遇到换行符、缓冲区被填满,或者主动调用fflush(stdout)时,缓冲区里的内容才会真正输出到终端。你的"ABC"就一直留在缓冲区里没发出来。 - 再看日志写入:你用
fprintf写文件后调用了fclose(f),而fclose会自动刷新该文件的缓冲区,所以日志内容能正常写入tmp.log,这部分没问题。 - 关键来了:当你调用
execvp时,它会完全替换当前子进程的整个地址空间——包括stdio的缓冲区。这时候缓冲区里还没来得及输出的"ABC"就被直接丢弃了,自然看不到任何输出。
解决办法(二选一即可)
- 给printf加上换行符,触发行缓冲自动刷新:
printf("ABC\n");
- 主动刷新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(<ime, &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
相关产品推荐
相关产品推荐

