Terminal 终端宽度IOCTL(当管道连接到以下位置时)
我有一个使用Terminal 终端宽度IOCTL(当管道连接到以下位置时),terminal,ioctl,less-unix,Terminal,Ioctl,Less Unix,我有一个使用 ioctl(file_descriptor_of_stdout, TIOCGWINSZ, &w); 获取终端宽度(用于打印阵列)。如果我直接在终端上运行我的程序,这工作得很好;然而,我经常通过较少的管道输出,用于分页和搜索。为了便于讨论,假设stderr也是通过管道传输的,所以我不能通过期望它实际到达终端来“欺骗” 现在,less本身确实考虑了终端的宽度——用于断开或切断线路。它不会以某种方式将此信息进一步传递给通过它传输的任何东西吗?您有多种选择: 有三个流(stdi
ioctl(file_descriptor_of_stdout, TIOCGWINSZ, &w);
获取终端宽度(用于打印阵列)。如果我直接在终端上运行我的程序,这工作得很好;然而,我经常通过较少的管道输出,用于分页和搜索。为了便于讨论,假设stderr也是通过管道传输的,所以我不能通过期望它实际到达终端来“欺骗”
现在,less本身确实考虑了终端的宽度——用于断开或切断线路。它不会以某种方式将此信息进一步传递给通过它传输的任何东西吗?您有多种选择:
- 有三个流(stdin、stdout和stderr),您的程序可以使用
等进行检查。重定向交互式程序的输出比重定向输入更常见,因此值得检查isatty(fileno(stdin))
- 如果没有任何流是终端,则可以打开与每个交互进程关联的
。这不一定是tty
,如运行在/dev/tty
中的shell的快速检查所示:xterm
- POSIX记录了这个程序,这似乎是一个很好的开始。但是,您的程序必须从管道读取路径名(比应用于标准流的
稍微复杂一些)。文件还说 当没有从标准输入读取输入时,应检查标准输入,以确定其是否为终端,如果是,则确定终端名称 也就是说,如果程序的标准输入被重定向(不是终端),isatty
对查找真正的终端没有帮助。tty
@einpoklum的评论提醒我POSIX还记录了库调用。顺便说一句,通常当一个程序通过一个特定的函数调用实现时,POSIX会记录该程序,说如果它使用该调用,它的行为“就好像”。但它并没有在
中提到这一点tty
- 如果没有标准流是终端,您可以尝试打开
。如果您的程序不是交互式的,则可能会失败,例如在/dev/tty
或后台运行。为了避免这似乎是一种奇怪的批评,偶尔会有人请求从cron
打开X应用程序。同样,POSIX记录了cron
/dev/tty
的fd
而不是stdout
的fd吗?@MarkSetchell:Hmm./dev/tty对于每个进程来说都是不同的,这取决于它在哪个终端上?是的,这是正确的。它针对每个进程。POSIX tty不是一个好的起点,它只是让ttyname()
library调用并打印结果(我检查了源代码)。但是尝试所有3个文件描述符不是一个坏主意。
$ 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, 1 Mar 10 16:09 /dev/pts/1