如果不是来自 stdio,(mysql)进程如何知道“它的”终端?

如果不是来自 stdio,(mysql)进程如何知道“它的”终端?

该计划的一件事mysql引起了我的注意。可以告诉它与标志交互地询问密码-p,在这种情况下,正如您所期望的,终端中会出现提示,并且输入的任何内容都会被接受为密码。但令我惊讶的是,即使您重定向所有三个,也会发生这种情况std{in,out,err}

$ mysql -p </dev/null >/dev/null 2>/dev/null
Enter password:

它也可以正确读取密码。如果重定向stderr到文件,可以检查登录是否失败。

进程如何知道在哪个终端上询问密码?它是否检查父进程的附加终端?

答案1

unix 进程可以从 /dev/tty 读取数据,从而绕过重定向。

答案2

用途 getpass()来自 libc(如果可用),手册页中描述如下:

getpass() 函数打开 /dev/tty (进程的控制终端),输出字符串提示符,关闭回显,读取一行(“密码”),恢复终端状态并再次关闭 /dev/tty。

答案3

它可以调用isattyunistd函数。

NAME
       isatty - test whether a file descriptor refers to a terminal

SYNOPSIS
       #include <unistd.h>

       int isatty(int fd);

DESCRIPTION
       The  isatty()  function  tests  whether  fd  is an open file descriptor
       referring to a terminal.

也许,正如 @Gerard H. Pille 指出的那样,mysql 根本不检查,而只是在/dev/tty您使用-p.

一些额外的细节

我检查了 glibc 源代码伊萨蒂实施

它只是使用该tcgetattr函数来获取文件描述符的终端功能。如果函数返回 true,则它是一个终端。

相关内容