为什么密码输入在管道 sudo 命令中起作用?

Kar*_*rlo 25 linux terminal sudo file-descriptors

如果我做:

sudo cat /etc/resolv.conf | less
Run Code Online (Sandbox Code Playgroud)

它会提示我输入密码,即使less(大概)需要stdin。在什么 fd 上显示密码提示以及它如何取回输入?

Bob*_*Bob 48

实际上,典型的 调用sudo根本不读取密码stdin。相反,sudo将直接访问控制终端(attypty,通过/dev/tty特殊文件)并直接输出提示和读取字符。这可以tgetpass.csudo源文件中看到。

还有一些其他场景:

  • 如果askpass指定了一个程序,例如在-A参数中,该程序将被调用。
  • 否则,如果您特别请求sudo从 读取stdin,例如使用-S标志 - 它也会将提示写入stderr。这就是MadHatter 的答案适用的情况。
  • 否则,如果没有tty可用
    • 如果禁用密码回显(默认情况下,由 中的visiblepw标志控制sudoers),sudo将报告错误:no tty present and no askpass program specified
    • 否则,sudo将回退到使用stdinstderr即使它没有特别要求。MadHatter 的回答也适用于此。


Mad*_*ter 10

管道将sudo cat的标准输出连接到less标准输入,因此sudo cat标准输入不受影响,并且能够接收密码。

至于提示,它在sudo cat的 stderr上熄灭;在 bash 中,尝试将其与 stdout 一起重定向,使用

sudo cat /etc/resolv.conf |& less
Run Code Online (Sandbox Code Playgroud)

看看反应有多么不同。

  • 虽然这个答案是正确的,因为 `sudo` 的 stdin 仍然使用示例命令连接到终端,但这与其获取密码的方式没有直接关系:默认情况下,`sudo` 不会通过 stdin 请求密码,也不会显示通过 `stderr` 提示——你可以试试 `2>/dev/null` 来确认。相反,`sudo` 直接访问 tty。 (16认同)