Насколько я понимаю, если я введу следующую команду в моем xterm:
$ ssh ir@localhost
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ir@localhost's password:
, тогда stdin и stdout процесса ssh
будут подключены к pty.Поэтому, когда я набираю пароль, ssh
просто читает его со стандартного ввода.
Но моя ментальная модель не может объяснить это:
$ yes | ssh ir@localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ir@localhost's password:
...
...
zsh: command not found: y
...
Здесь, *Stdin 1015 * подключен к pty, а стандартный вывод yes
направляется к stdin ssh
.Таким образом, ssh
должен получать поток y
s, но он достаточно умен, чтобы сказать, что его стандартный ввод не является tty, и что содержимое стандартного ввода не должно интерпретироваться как пароль.Вместо этого y
s буферизируются, и после успешного входа в систему они доставляются непосредственно в процесс bash на удаленном конце.
Но тогда как ssh может получить пароль, который яя набираю? Pty отправляет мой пароль на yes
, который сбрасывает его на пол.
Кроме того, заявление ssh
о том, что pty не выделяется, представляется ложью.Следующий фрагмент распечатывает, является ли stdin tty:
$ [ -t 0 ] && echo true || echo false;
true
Когда я передаю эту команду по конвейеру в ssh, она первоначально выводит «false», как и ожидалось:
$ echo "[ -t 0 ] && echo true || echo false;" | ssh ir@localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ir@localhost's password:
...
false
$ [ -t 0 ] && echo true || echo false;
true
Но когда я запускаю ту же команду на удаленной оболочке, она выводит «true».Я даже могу открыть vim
, и когда я изменю размер моего локального терминала, vim
изменяет размер текста, который он отображает соответствующим образом.Это возможно только в том случае, если клиент ssh
передает информацию об изменении размера по проводам, и если sshd
уведомляет процесс vim
, как это делает pty.
Интересно, когда я нажимаю Ctrl+ C, сеанс ssh
немедленно прекращается.Я объясняю это тем, что pty перехватывает Ctrl + C и отправляет SIGINT как yes
, так и ssh
.Если бы ssh
выделил pty, он перехватил бы сигнал и передал его по проводному соединению на удаленный хост, и любой процесс, работающий удаленно, был бы прерван.Но так как ssh
1051 * не не выделил pty, он просто умер.Так что эта часть ожидается ... но я до сих пор не понимаю, почему [ -t 0 ]
проходит на удаленной оболочке, и как ssh
может читать пароль, даже когда yes
передается по нему.