25

If I do:

sudo cat /etc/resolv.conf | less

It will prompt me for the password, even though less (presumably) takes stdin. Over what fd's is the password prompt shown and how does it get the input back?

Karel
  • 629
  • 9
  • 16

2 Answers2

49

Actually, a typical invocation of sudo does not read the password from stdin at all. Instead, sudo will directly access the controlling terminal (a tty or pty, via the /dev/tty special file) and output the prompt and read characters directly. This can be seen in the tgetpass.c file in the sudo source.

There are a few other scenarios:

  • If an askpass program is specified, e.g. in the -A param, that program will be invoked.
  • Otherwise, if you specifically request sudo to read from stdin, e.g. with the -S flag -- and it will also write the prompt to stderr. This is the case where MadHatter's answer applies.
  • Otherwise, if there is no tty available
    • If password echo is disabled (it is by default, controlled by the visiblepw flag in sudoers), sudo will report an error: no tty present and no askpass program specified
    • Otherwise, sudo will fall back to using stdin and stderr even if it was not specifically requested. MadHatter's answer will also apply here.
Bob
  • 1,536
  • 12
  • 17
10

The pipe connects sudo cat's stdout to less's stdin, so sudo cat's stdin is unaffected, and able to receive the password.

As for the prompt, it goes out on sudo cat's stderr; in bash, try redirecting that along with stdout, using

sudo cat /etc/resolv.conf |& less

and see how different the response is.

MadHatter
  • 78,442
  • 20
  • 178
  • 229
  • 16
    While this answer is correct in that `sudo`'s stdin is still connected to the terminal with the example command, that's not directly relevant to how it gets its password: by default `sudo` will not request passwords via stdin nor will it show the prompt via `stderr` -- you can try `2>/dev/null` to confirm that. Instead, `sudo` directly accesses the tty. – Bob Oct 27 '15 at 13:01