1

我有这个程序使用

ioctl(file_descriptor_of_stdout, TIOCGWINSZ, &w);

获取终端宽度(用于打印数组)。如果我直接在终端上运行我的程序,这很好用;但是,我经常通过 less 管道输出,用于分页和搜索。为了讨论起见,假设 stderr 也是通过管道传输的,所以我不能通过期望它实际进入终端来“作弊”。

现在,less 本身确实考虑了终端的宽度 - 用于断线或切断它们。它不会以某种方式将这些信息进一步传达给通过它传输的任何东西吗?

4

1 回答 1

2

您有不止一种选择:

  • 有三个流(stdinstdoutstderr),您的程序可以使用它们isatty(fileno(stdin))等进行检查。为交互式程序重定向输出比重定向输入更常见,因此值得检查。
  • 如果没有一个流是终端,您可以打开tty与每个交互进程关联的终端。这不一定/dev/tty,如从运行的 shell 中进行的快速检查所示xterm
    $ ls -l /dev/tty;tty;ls -l `tty`
    crw-rw-rw- 1 root root 5, 0 Mar 10 15:46 /dev/tty
    /dev/pts/1
    crw--w---- 1 tom tty 136,2010 年 3 月 1 日 16:09 /dev/pts/1
  • POSIX 记录了该tty程序,这似乎是一个不错的起点。isatty但是,您的程序必须从管道中读取路径名(比应用于标准流稍微复杂一些)。该文件还说

    虽然没有从标准输入读取输入,但应检查标准输入以确定它是否是终端,如果是,则确定终端的名称。

    也就是说,如果您的程序的标准输入被重定向(不是终端),tty则无法找到真正的终端。
    @einpoklum 的评论提醒我,POSIX 还记录了 library call ttyname。顺便说一句,通常当一个程序由一个特定的函数调用实现时,POSIX 记录该程序,说它的行为“好像”如果它使用了那个调用。但它并没有提到这一点tty

  • 如果标准流都不是终端,您可以尝试打开/dev/tty. 如果您的程序不是交互式的,则可能会失败,例如,在后台运行cron或在后台运行。为了避免这似乎是一个奇怪的批评,偶尔会有从cron. 同样,POSIX 文档(在10.1 目录结构和文件
于 2016-03-10T21:23:58.387 回答