Мне иногда нужно запускать команды от имени пользователя root на удаленном сервере и анализировать вывод команды на моем локальном сервере.Удаленный сервер не разрешает вход в систему с правами root ssh
, но sudo
настроен так, что для него требуется пароль.Упрощенный пример того, что мне нужно сделать, это
ssh remote sudo echo bar | tr bar foo
(Очевидно, что в этом упрощенном примере нет веской причины для запуска echo
на другом компьютере, отличном от tr
: это всего лишьПример с игрушкой, объясняющий, что я пытаюсь сделать.)
Если я запускаю указанную выше команду, я получаю ошибку, что у sudo нет способа запросить пароль:
richard@local:~$ ssh remote sudo echo bar | tr bar foo
sudo: no tty present and no askpass program specified
Один из способов исправить это, добавив параметр -t
к ssh
.Если я это сделаю, sudo
ожидает и принимает пароль, но вывод псевдотерминала ssh
отправляется на стандартный вывод, что означает, что сообщение с подсказкой sudo передается на tr
и не отображается для пользователя.Если пользователь не знает, sudo
ждет пароля, он будет думать, что скрипт завис, и передача сообщения с подсказкой в канал, вероятно, прервет дальнейшую обработку:
richard@local:~$ ssh -t remote sudo echo bar | tr bar foo
[sudo] posswood foo oichood:
foo
(Это, по-видимому, глупоПример показывает, что приглашение было обработано командой tr
, к которой передается вывод.)
Другой способ исправить это, добавив параметр -S
к sudo
.Если я это сделаю, sudo
запрашивает пароль у stderr, поэтому приглашение не передается по конвейеру.Это хорошо, но sudo
также принимает пароль на стандартном вводе, что означает, что он передается на терминал, где любой, кто смотрит через плечо пользователя, может его прочесть:
richard@local:~$ ssh remote sudo -S echo bar | tr bar foo
[sudo] password for richard: p8ssw0rd
foo
Я нашел неуверенные способы обходапроблемы с этими двумя вариантами, но мои обходные пути наталкиваются на проблему, если пользователь неправильно вводит свой пароль в первый раз.Это само по себе является проблемой.Примерами этого являются:
richard@local:~$ echo "[sudo] password for $USER:"; \
ssh -t remote sudo echo bar | tail +2 | tr bar foo
richard@local:~$ (read -s password; echo $password; echo >&2) \
| ssh remote sudo -S echo bar | tr bar foo
Я уверен, что должно быть хорошее решение для этого, так как это не редкость, что хотеть сделать.Есть идеи?