当输出被重定向到日志文件时,无法获取终端宽度

编程语言 2026-07-09

在下面的程序中,我想获取终端宽度以用于进度条显示。应用直接输出时会返回正确的值,但输出被重定向后就会失败。应该如何修复?

main.c

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>

size_t get_terminal_width(const size_t fixed_size) {
    struct winsize w;
    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == -1) {
        printf("failed to get terminal width\n");
        exit(EXIT_FAILURE);
    }

    return (w.ws_col > fixed_size ? w.ws_col - fixed_size : 1);
}

int main() {
    printf("%zu\n", get_terminal_width(50));
}

./a.out 输出

104

./a.out |& tee a.txt 输出

failed to get terminal width

./a.out >> b.txt 输出

failed to get terminal width

解决方案

You are using ioctl(STDOUT_FILENO, ...). You are asking the system about what standard output is. If output is redirected to a file or a pipe, you are using the ioctl call on that file or pipe, which is not what you want.

简单的变通方法

  • 如果没有理由重定向标准输出或标准错误流,就直接使用它们:

  • ioctl(STDIN_FILENO, ...)

  • ioctl(STDERR_FILENO, ...)
  • 如果你确定这段代码只会在Linux或其他类Unix系统上运行(永远不会在Windows、MS/DOS等上运行),你可以尝试使用 /dev/tty

c fdcon = open("/dev/tty", O_RDONLY); // test fdcon != -1... if (ioctl(fdcon, TIOCGWINSZ, &w) == -1) { ... } close(fdcon); // never forget to release...

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章