我只想在我的外壳“连接”到终端时才执行某些操作,即仅当我的标准输入来自终端的输入并且我的标准输出(和标准错误?也许没关系)被打印/回显到一个终端。
在不直接依赖GNU / Linux细节(例如/proc/self
)的情况下,我该怎么做?
我只想在我的外壳“连接”到终端时才执行某些操作,即仅当我的标准输入来自终端的输入并且我的标准输出(和标准错误?也许没关系)被打印/回显到一个终端。
在不直接依赖GNU / Linux细节(例如/proc/self
)的情况下,我该怎么做?
Answers:
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 ...
是写此条件的惯用方式。
在已经给出的最佳答案的基础上,仅需多加说明。请注意,[ -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
):
printf
失败,但如果stdin是在读写模式下打开的tty设备,则将产生副作用将该序列发送到另一端。例如,在上面的ssh示例中,该命令实际上会将序列发送到终端(但不会在stdin上回复)