当输出被重定向到日志文件时,无法获取终端宽度
在下面的程序中,我想获取终端宽度以用于进度条显示。应用直接输出时会返回正确的值,但输出被重定向后就会失败。应该如何修复?
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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。