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

Docker容器中C语言程序无法输出日志问题求助

问题描述

尝试将一个简单的Hello World C程序容器化到Docker中,使用printf、syscall等方式输出内容,但无法通过docker logs查看日志。参考官方hello-world的C代码后仍未解决,以下是相关代码、配置及操作记录:

我的C代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>

int main() 
{
  printf("hello world\n");
  syscall(SYS_write, STDOUT_FILENO, "hello world", sizeof("hello world") - 1);
}

使用的Docker命令

sudo docker build -t hwsha .
sudo docker run --name hwsha-pr  hwsha
sudo docker logs hwsha-pr

Dockerfile内容

FROM ubuntu:latest
RUN apt-get update && apt-get install -y gcc vim 
COPY hello.c .
RUN  gcc hello.c -o hello
CMD ["./hello"]

相关输出记录

Docker inspect日志路径检查

/home/ravi/>sudo docker inspect 7061172c55c1 | grep log
        "LogPath": "/var/lib/docker/containers/7061172c55c12d88778b021b6c72f617b25a0eaa770605c678c5efe409afd043/7061172c55c12d88778b021b6c72f617b25a0eaa770605c678c5efe409afd043-json.log",

/home/ravi/>sudo cat /var/lib/docker/containers/7061172c55c12d88778b021b6c72f617b25a0eaa770605c678c5efe409afd043/7061172c55c12d88778b021b6c72f617b25a0eaa770605c678c5efe409afd043-json.log
/home/ravi/>

构建与运行命令输出

/home/ravi/>sudo docker build -t hwsha .
Sending build context to Docker daemon  4.096kB
Step 1/5 : FROM ubuntu:latest
 ---> 74f2314a03de
Step 2/5 : RUN apt-get update && apt-get install -y gcc vim
 ---> Using cache
 ---> d8006c91e13d
Step 3/5 : COPY hello.c .
 ---> Using cache
 ---> a5060319d17a
Step 4/5 : RUN  gcc hello.c -o hello
 ---> Using cache
 ---> 684a11ee4cfb
Step 5/5 : CMD ["./hello"]
 ---> Using cache
 ---> e6bde96f1091
Successfully built e6bde96f1091
Successfully tagged hwsha:latest
/home/ravi/>sudo docker run --name hwsha-pr -d hwsha
d9ae3fd4ac383a290101d99c18be7d681acd065b3db66e454aa98299cb5a43c7
/home/ravi/>sudo docker logs -t hwsha-pr    ====> no logs at this point
/home/ravi/>
问题原因及解决方案

核心问题点

  1. 头文件缺失:代码中使用了STDOUT_FILENO,但未包含定义该常量的<unistd.h>头文件,编译时产生的警告会导致syscall调用参数无效,无法正确输出内容。
  2. printf缓冲区未刷新:printf默认采用行缓冲模式,当输出目标不是终端(Docker容器中stdout默认非终端)时,即便有换行符\n,缓冲区也不会自动刷新,程序退出前未手动刷新的话,内容会丢失。
  3. 程序退出逻辑不明确:main函数未明确返回值,虽然C标准默认返回0,但部分环境下可能导致程序退出过程异常,影响缓冲区刷新。

修复步骤

1. 修改C代码,补全依赖并确保输出正常

添加缺失头文件,手动刷新printf缓冲区,明确程序退出逻辑:

#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>  // 补全STDOUT_FILENO的定义

int main() 
{
  printf("hello world\n");
  fflush(stdout);  // 手动刷新printf的缓冲区
  syscall(SYS_write, STDOUT_FILENO, "hello world\n", sizeof("hello world"));  // 添加换行符优化日志可读性
  return 0;  // 明确程序正常退出
}

2. 重新构建并运行容器

执行以下命令:

sudo docker build -t hwsha .
sudo docker rm -f hwsha-pr  // 删除旧容器
sudo docker run --name hwsha-pr hwsha
sudo docker logs hwsha-pr

可选优化:简化Dockerfile

原Dockerfile安装了非必需的vim,且ubuntu镜像体积较大,可优化为更小的镜像并减少依赖:

FROM alpine:latest
RUN apk add --no-cache gcc musl-dev
COPY hello.c .
RUN gcc hello.c -o hello
CMD ["./hello"]

验证结果

修复后重新运行容器,执行docker logs即可看到输出的"hello world"内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:38:15