如果我做:
sudo cat /etc/resolv.conf | less
它会提示我输入密码,尽管 less(大概)采用 stdin。密码提示显示在哪些 fd 上,它如何获取输入?
答案1
实际上,典型的调用根本sudo
不会从中读取密码stdin
。相反,sudo
将直接访问控制终端(通过特殊文件 atty
或)并输出提示并直接读取字符。这可以在源文件中看到。pty
/dev/tty
tgetpass.c
sudo
还有其他几种情况:
- 如果
askpass
指定了一个程序,例如在-A
参数中,那么将调用该程序。 - 否则,如果你明确要求
sudo
从 读取stdin
,例如使用标志-S
-- ,它也会将提示写入stderr
。这是MadHatter 的回答适用。 - 否则,如果没有
tty
可用的- 如果密码回显被禁用(默认情况下,由
visiblepw
中的标志控制sudoers
),sudo
将会报告错误:no tty present and no askpass program specified
- 否则,即使没有特别要求,
sudo
也会恢复使用stdin
。stderr
MadHatter 的回答也适用于此。
- 如果密码回显被禁用(默认情况下,由
答案2
管道将sudo cat
的标准输出 连接到less
的标准输入,因此sudo cat
的标准输入不受影响,并且能够接收密码。
至于提示,它会在sudo cat
stderr 上发出;在 bash 中,尝试将其与 stdout 一起重定向,使用
sudo cat /etc/resolv.conf |& less
看看反应有何不同。