Linux printf 输出 重定向输出 无法打印问题分析以及解决方法

时间:2022-01-22 10:35:06

1 说明

有时候,在linux 环境下,使用printf 无法打印信息,导致调试很不方便。

2 原因分析

2.1 没有刷新缓冲区

默认Linux 设置了打印缓冲功能,当打印缓冲区未满情况下,不打印。如果需要打印,增加fflush(stdout) 语句,用于刷新缓冲区,即可打印。

2.2 进程关闭了标准输入输出功能。

在系统或者进程中,关闭了printf功能,将输入输出重定向到 /dev/null 中,所以printf的输出,都输出到/dev/null,自然无法打印信息。

查看方法: 1、ps 查看调用printf的进程号,如进程号为200
2、进入进程号的文件说明文件夹

cd /proc/200/fd

3、查看文件属性

# ls -al
dr-x------    2 root     root             0 Apr 28 11:36 .
dr-xr-xr-x    7 root     root             0 Apr 28 11:00 ..
lrwx------    1 root     root            64 Apr 28 11:36 0 -> /dev/null
lrwx------    1 root     root            64 Apr 28 11:36 1 -> /dev/null
lrwx------    1 root     root            64 Apr 28 11:36 2 -> /dev/null

从中可以看到 0、1、2 文件都被指向 “dev/null”
shell 中运行的进程,默认会有3个文件描述符存在(0、1、2)
0 ——— 与进程的标准输入相关联。
1 ——– 与进程的标准输出相关联。
2 ——— 与进程的标准错误输出相关联。
0、1、2都被指向 /dev/null,所以 输入、输出、标准错误的信息都指向null(也就是所谓的黑洞),往null 丢数据,自然什么都没有显示。

3 解决方法

重定向输入、输出、错误信息。
例如,本设备的输出串口为 /dev/ttyAMA3,则进行设置的代码 test.c 如下

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>

// set the stdio, can support printf function to display message.
static void set_stdio(void)
{
    int fd = -1;

    fd = open("/dev/console", O_RDWR);
    if (fd < 0)
    {
        fprintf(stderr, "errno=%d (%s)\n", errno, strerror(errno));
        return;
    }
    dup2(fd, 0);    // standrad input set 
    dup2(fd, 1);    // standrad ouput set
    dup2(fd, 2);    // standrad error set
    close(fd);
}


int main(int argc, char** argv)
{
    set_stdio();
    printf("--test printf function--\n");
    fflush(stdout);

    return 0;
}

4 测试结果

  1. 编译
arm-none-linux-gnueabi-gcc -o test test.c

2、将程序下载到嵌入式开发板,运行测试结果

# ./set 
--test printf function--