该计划的一件事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
它可以调用isatty
unistd函数。
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,则它是一个终端。