Мой вопрос можно рассматривать как продолжение Как сделать разницу по ssh? с небольшим поворотом.
macOS Sierra (10.12.3)
OpenSSH 7.3
Я пытаюсь напечатать diff
между двумя файлами, один из которых находится на удаленном хосте и требует sudo
для чтения.
Если бы этот удаленный файл был доступен для чтения моим удаленным пользователем (или если бы я мог выполнить команду с флагом sudo NOPASSWD
) Я бы просто выполнил:
diff LOCALFILE <(ssh host 'cat REMOTEFILE')
Однако мне нужно пройти аутентификацию, чтобы выполнить удаленную команду, а это значит, что мне нужно выделить псевдотерминал с ssh -t
, и следующее выполнение никогда не завершается:
diff LOCALFILE <(ssh -t host 'sudo cat REMOTEFILE')
ps
показывает мне, что ssh
процесс остановлен:
STAT TIME COMMAND
S+ 0:00.00 diff LOCALFILE /dev/fd/12
T 0:00.03 ssh -t host sudo cat REMOTEFILE
В ssh
процесс не отвечает на SIGTERM в этот момент, и описанный выше файловый дескриптор не существует:
❯ ls -l /dev/fd
total 0
crw--w---- 1 me tty 16, 2 Feb 23 17:36 0
crw--w---- 1 me tty 16, 2 Feb 23 17:36 1
crw--w---- 1 me tty 16, 2 Feb 23 17:36 2
dr--r--r-- 1 root wheel 0 Feb 23 09:33 4
Я могу наблюдать точно такое же поведение каждый раз, когда использую ssh -t
внутри процесса подстановки, независимо от того, нужен ли пароль для sudo
(при этом я понимаю использование -t
сомнительно, если на удаленном хосте не ожидается ввода).
я использую diff
в качестве примера, но мой вопрос на самом деле более общий: есть ли способ использовать Bash замена процесса вместе с выделением псевдотерминала SSH?
Вы можете заставить sudo взять пароль из STDIN, используя -S
вариант, за этот пост суперпользователя. Таким образом, синтаксис diff LOCALFILE <(ssh host 'echo <password> | sudo -S cat REMOTEFILE')
должен делать то, что вам нужно, без необходимости в псевдотерминале.