【问题标题】:Getting terminal size when running with "watch" in Linux在 Linux 中使用“watch”运行时获取终端大小
【发布时间】:2020-01-13 13:38:14
【问题描述】:

我有这个简单的测试程序:

#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[], char *envp[])
{
    struct winsize w;
    if (!ioctl(fileno(stdout), TIOCGWINSZ, &w)) {
        printf("width %d\n", w.ws_col);
    } else {
        printf("%s", strerror(errno));
    }
    return 0;
}

如果从终端本身运行,将返回终端窗口的大小,但由于某种原因,如果通过watch 命令运行,它只会在返回不合适的 IOCTL FOR DEVICE 的 ioctl() 上失败。

知道为什么吗?获取终端窗口大小的最可靠方法是什么?

【问题讨论】:

  • 我建议你先检查isatty...比如isatty(fileno(stdout))。我的猜测是FILENO_STDOUT(标准输出描述符)不会去终端,而是去管道。

标签: c linux terminal


【解决方案1】:

重点是,程序的标准输出不再是终端,而是一个到watch管道,它将收集程序输出并显示它。因此,您无法从标准输出文件描述符中确定宽度。

但是,stdin 仍然连接到终端,因此您可以使用 fileno(stdin) 来获取正确的终端大小:

if (!ioctl(fileno(stdin), TIOCGWINSZ, &w)) {
    printf("width %d\n", w.ws_col);

【讨论】:

  • 通常,stderr 是最适合使用的文件流(描述符)。您还可以检查描述符后面的设备是否是终端 —isatty(), IIRC。
猜你喜欢
  • 2012-04-05
  • 2013-05-10
  • 2020-10-10
  • 1970-01-01
  • 2014-06-15
  • 2011-10-12
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多