Назад | Перейти на главную страницу

Почему ввод пароля работает в конвейерной команде sudo?

Если я сделаю:

sudo cat /etc/resolv.conf | less

Он предложит мне ввести пароль, хотя стандартный ввод (предположительно) занимает меньше. На каком fd отображается запрос пароля и как он возвращает ввод?

Собственно, типичный призыв sudo не читает пароль от stdin вообще. Вместо, sudo будет напрямую обращаться к управляющему терминалу ( tty или pty, через /dev/tty специальный файл) и выводить подсказку и читать символы напрямую. Это можно увидеть в tgetpass.c файл в sudo источник.

Есть еще несколько сценариев:

  • Если askpass программа указана, например в -A param, эта программа будет вызвана.
  • В противном случае, если вы специально запросите sudo читать из stdin, например с -S флаг - и он также напишет приглашение stderr. Это тот случай, когда Ответ Безумного Шляпника применяется.
  • В противном случае, если нет tty доступный
    • Если эхо пароля отключено (по умолчанию оно контролируется visiblepw флаг в sudoers), sudo сообщит об ошибке: no tty present and no askpass program specified
    • В противном случае, sudo вернется к использованию stdin и stderr даже если это не было специально запрошено. Ответ Безумного Шляпника также будет применяться здесь.

Труба соединяет sudo catстандартный вывод на lessстандартный ввод, так что sudo catstdin не изменяется и может получать пароль.

Что касается подсказки, она гаснет sudo catstderr; в bash попробуйте перенаправить это вместе с stdout, используя

sudo cat /etc/resolv.conf |& less

и посмотрите, насколько разные ответы.