如何检查我的外壳是否在终端中运行?


Answers:


33

isatty是用于检查this的函数-t,该test命令标志可从外壳脚本访问该标志

-t file_descriptor

如果文件描述符号file_descriptor已打开并与终端关联,则为true 。如果file_descriptor不是有效的文件描述符号,或者文件描述符号file_descriptor没有打开,或者如果它打开但未与终端关联,则为False 。

您可以使用以下命令检查FD 0(标准输入)是否为TTY:

test -t 0

您可以对FD 1和FD 2执行相同的操作,以检查输出和错误流,或全部检查:

test -t 0 -a -t 1 -a -t 2

如果描述符连接到终端,则命令返回0(成功),否则返回false。

test也可以作为[“托架测试” 的命令使用:

 if [ -t 0 ] ; then ...

是写此条件的惯用方式。


8

我想这是重复的,但我找不到。使用

[ -t 0 ]

[ -t 1 ]

分别测试标准输入和输出是否连接到端子。man test有详细信息。


7

在已经给出的最佳答案的基础上,仅需多加说明。请注意,[ -t 0 ]测试文件描述符0是否已打开,该文件是具有tty行规范的设备文件(通常是通过检查无害术语ioctl()成功完成的)。

而且,这不一定意味着在另一端有一个终端或终端仿真器(真实用户在键盘上键入)(尽管在大多数情况下,而且可能是您关心的大多数情况下),近似)。

tty和pty设备还可以用于数据传输或用作进程间通信机制。

例如,一个人可以做:

(stty raw -echo; myscript) < /dev/ttyS0

将通过RS232接收到的信息提供给myscript

echo test | ssh -tt host myscript

将具有myscript的标准输入是一个PTY装置(具有sshd在另一端处,并且最终(穿过ssh连接)不是终端,而是由供给管echo

要进一步检查该RS232线路或pty的另一端是否有终端,您还可以检查是否$TERM已设置变量且该变量为非空([ -n "$TERM" ]),并通过该fd 发送设备状态报告转义序列,并检查是否收到响应(除了[ -t 0 ]和之外[ -n "$TERM" ])。

printf >&0 '\e[5n'

\e[0n大多数终端都会回复一个。

现在有几个问题,因此不建议您这样做,除非您要运行可视化TUI应用程序进行检查(在这种情况下,最好使用ncurses,而不是DSR,您宁愿发送设备标识转义序列来查询终端的类型,而不是通过$TERM):

  • 值得庆幸的是,在大多数情况下,stdin不是终端,它将在只读模式下打开,这将导致printf失败,但如果stdin是在读写模式下打开的tty设备,则将产生副作用将该序列发送到另一端。例如,在上面的ssh示例中,该命令实际上会将序列发送到终端(但不会在stdin上回复)
  • 很难可靠,方便地阅读回复。您需要临时更改tty行规则,并一次读取一个字节。您还需要确定一个超时时间,如果超时,如果没有看到答复,您将放弃并确定没有终端。如果要考虑人们通过卫星连接拨号,则意味着超时时间较长。
  • 在后台读取终端会中止带有SIGTTIN信号的脚本。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.