为什么密码input工作在pipe道sudo命令?

如果我做:

sudo cat /etc/resolv.conf | less 

它会提示我input密码,即使更less(大概)需要stdin。 在fd上显示的是密码提示,它是如何得到input的?

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

还有其他一些情况:

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

pipe道将sudo cat的stdout连接到less的stdin,所以sudo cat的stdin不受影响,并且能够接收密码。

至于提示,就是sudo cat的情况。 在bash中,尝试使用stdoutredirect

 sudo cat /etc/resolv.conf |& less 

看看反应有多不同。