> Мне напоминают, что ssh не выделяет псевдо-tty. Что происходит? Было бы обогатить вопрос, чтобы понять, в чем проблема.
эфир
5
@ Air Нет проблемы, которую я пытался решить. Был выбор в том, как реализован ssh, который я пытался понять. Вопрос очень ясен, и ответ Эндрю Б хорошо отвечает на этот вопрос. Ответ можно резюмировать так: работа ssh -tвсегда плохая, потому что это может привести к сбою некоторых команд странным образом. Принимая во внимание, что выполнение команды, которой нужен PTY без единого, приводит к ясному сообщению об ошибке, что вам нужен терминал.
час. Оуэнс
Ответы:
73
Основным отличием является концепция интерактивности . Это похоже на локальный запуск команд внутри скрипта, а не на их ввод самостоятельно. Разница заключается в том, что удаленная команда должна выбрать значение по умолчанию, а неинтерактивный - самый безопасный. (и обычно самый честный)
STDIN
Если PTY выделен, приложения могут обнаружить это и знать, что безопасно запрашивать у пользователя дополнительный ввод, не ломая вещи. Есть много программ, которые пропускают этап запроса пользователя для ввода, если нет терминала, и это хорошо. В противном случае скрипты будут зависать без необходимости.
Ваш ввод будет отправлен на удаленный сервер на время выполнения команды. Это включает в себя контрольные последовательности. Хотя Ctrl-cпрерывание обычно приводит к немедленному прерыванию цикла в команде ssh, ваши управляющие последовательности вместо этого будут отправляться на удаленный сервер. Это приводит к необходимости «забивать» нажатие клавиши, чтобы гарантировать, что оно прибывает, когда управление покидает команду ssh, но до начала следующей команды ssh.
Я бы предостерег от использования ssh -tв необслуживаемых сценариях, таких как crons. Неинтерактивная оболочка, требующая от удаленной команды интерактивного поведения для ввода, вызывает все виды проблем.
Вы также можете проверить наличие терминала в ваших собственных скриптах оболочки. Чтобы протестировать STDIN с более новыми версиями bash:
# fd 0 is STDIN
[ -t 0 ]; echo $?
STDOUT
Когда альясинг sshк ssh -t, вы можете ожидать , чтобы получить дополнительный возврат каретки в концах вашей линии. Возможно, он не виден вам, но он есть; это будет отображаться как ^Mпри передаче cat -e. Затем вы должны приложить дополнительные усилия, чтобы гарантировать, что этот управляющий код не будет назначен вашим переменным, особенно если вы собираетесь вставить этот вывод в базу данных.
Существует также риск того, что программы будут предполагать, что они могут отображать выходные данные, которые не подходят для перенаправления файлов. Обычно, если вы перенаправляете STDOUT в файл, программа распознает, что ваш STDOUT не является терминалом, и пропускает любые цветовые коды. Если перенаправление STDOUT происходит с выхода клиента ssh, а с удаленным концом клиента связан PTY, удаленные программы не смогут сделать такое различие, и вы получите терминальный мусор в выходном файле. Перенаправление вывода в файл на удаленном конце соединения должно по-прежнему работать должным образом.
Вот тот же тест bash, что и ранее, но для STDOUT:
# fd 1 is STDOUT
[ -t 1 ]; echo $?
Хотя можно обойти эти проблемы, вы неизбежно забудете разработать сценарии вокруг них. Все мы делаем в какой-то момент. Члены вашей команды могут также не понимают / помнить , что этот псевдоним на месте, что в свою очередь создает проблемы для вас , когда они пишут сценарии , которые используют свой псевдоним.
Псевдоним очень похож sshна ssh -tтот случай, когда вы нарушите принцип дизайна наименьшего удивления ; люди будут сталкиваться с проблемами, которых они не ожидают, и могут не понимать, что их вызывает.
Почти создается впечатление, что я работал в команде, которая сделала это ...
Эндрю Б
Сфера охвата этого ответа, это здорово. Но вопрос имел более широкий охват, по сути желая знать ВСЕ различия (чего ожидать). Дополнительная информация: На уровне процесса -t СНАЧАЛА выделит tty, а затем запустит оболочку (по пути поиск / etc / profile и ~ / .bash_profile), а затем запустит команду. Без -t ssh установит в исходное состояние различные файлы env (/etc/bash.bashrc, затем ~ / .bashrc), а затем запустит вашу команду. Это означает, что вы можете видеть очень различное поведение в каждом: короче $ PATH, возможно, bash «унарная» ошибка, потому что вы предполагаете, что ENV var там нет ...
Scott Prive
@Crossfit Мы рассмотрели тему «входящие в систему оболочки против входа в систему» в комментариях к другому ответу, но мы не вдавались в исчерпывающую разбивку экологических различий, потому что ФП уже рассмотрел вопрос, отвечающий их конкретным потребностям. Пожалуйста, не стесняйтесь добавлять детали, где вы видите место для этого, поскольку это может помочь другим, кто сталкивается с этим Q & A.
Эндрю Б
33
Escape-символы SSH и передача двоичных файлов
Одно преимущество, которое не было упомянуто в других ответах, состоит в том, что при работе без псевдотерминала экранирующие символы SSH, такие как ~C, не поддерживаются ; это позволяет программам безопасно передавать двоичные файлы, которые могут содержать эти последовательности.
Доказательство концепции
Скопируйте двоичный файл, используя псевдо-терминал:
Это особенно важно для программ, таких как scpили rsyncкоторые используют SSH для передачи данных. Это подробное описание того, как работает протокол SCP, объясняет, как протокол SCP состоит из смеси текстовых сообщений протокола и данных двоичного файла.
OpenSSH помогает защитить вас от себя
Стоит отметить, что даже если этот -tфлаг используется, sshклиент OpenSSH откажется выделять псевдо-терминал, если обнаружит, что его stdinпоток не является терминалом:
$ echo testing | ssh -t anthony@remote_host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb
Вы по-прежнему можете заставить клиента OpenSSH выделить псевдо-терминал с помощью -tt:
Хорошо, но вывод с отступом /: Вы случайно не знаете, можете ли вы вернуть его автоматически (в стиле unix)?
Boop
1
Подумайте о обратной совместимости.
2 основных режима ssh: интерактивный вход в систему с tty и указанная команда без tty, потому что это были точные возможности rloginи rshсоответственно. ssh необходимо было предоставить расширенный набор функций rlogin/ rshдля успешной замены.
Таким образом, значения по умолчанию были определены до рождения ssh. Комбинации типа «Я хочу указать команду и получить tty» должны были быть доступны с новыми опциями. Радуйтесь , что по крайней мере у нас есть этот вариант сейчас, в отличие от , когда мы использовали rsh. Мы не обменяли никаких полезных функций на получение зашифрованных соединений. Мы получили бонусы!
-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
Это позволяет вам получить своего рода «оболочку» на удаленном сервере. Для серверов, которые не предоставляют доступ к оболочке, но разрешают SSH (т. Е. Github является известным примером доступа к SFTP), использование этого флага приведет к тому, что сервер отклонит ваше соединение.
В оболочке также есть все ваши переменные окружения (например $PATH), поэтому для выполнения сценариев обычно требуется tty.
Это не отвечает на вопрос. Я уже знаю, как выделить псевдо-tty. Я хочу знать, почему я не должен всегда выделять один.
час. Оуэнс
1
@ Chas.Owens Потому что, как я указал в ответе, некоторые SSH-серверы не разрешают tty-доступ, и соединение будет разорвано, если вы запросите один из них с сервера.
Натан С,
5
Я думаю, что вы можете запутать некоторые термины. Это не оболочка просто потому, что с ней связана PTY. Есть три общих типа оболочки: non-interactive, interactiveи login. loginявляется дополнительной характеристикой двух других типов оболочек. Перестановки этих трех параметров определяют, какие файлы получены при входе в систему, что, в свою очередь, влияет на то, как будет инициализироваться среда. (переменные, как вы упоминали)
Эндрю Б
3
@AndrewB Ты прав ... Я тоже кое-что узнал из этого вопроса. :)
ssh -t
всегда плохая, потому что это может привести к сбою некоторых команд странным образом. Принимая во внимание, что выполнение команды, которой нужен PTY без единого, приводит к ясному сообщению об ошибке, что вам нужен терминал.Ответы:
Основным отличием является концепция интерактивности . Это похоже на локальный запуск команд внутри скрипта, а не на их ввод самостоятельно. Разница заключается в том, что удаленная команда должна выбрать значение по умолчанию, а неинтерактивный - самый безопасный. (и обычно самый честный)
STDIN
Ctrl-c
прерывание обычно приводит к немедленному прерыванию цикла в команде ssh, ваши управляющие последовательности вместо этого будут отправляться на удаленный сервер. Это приводит к необходимости «забивать» нажатие клавиши, чтобы гарантировать, что оно прибывает, когда управление покидает команду ssh, но до начала следующей команды ssh.Я бы предостерег от использования
ssh -t
в необслуживаемых сценариях, таких как crons. Неинтерактивная оболочка, требующая от удаленной команды интерактивного поведения для ввода, вызывает все виды проблем.Вы также можете проверить наличие терминала в ваших собственных скриптах оболочки. Чтобы протестировать STDIN с более новыми версиями bash:
STDOUT
ssh
кssh -t
, вы можете ожидать , чтобы получить дополнительный возврат каретки в концах вашей линии. Возможно, он не виден вам, но он есть; это будет отображаться как^M
при передачеcat -e
. Затем вы должны приложить дополнительные усилия, чтобы гарантировать, что этот управляющий код не будет назначен вашим переменным, особенно если вы собираетесь вставить этот вывод в базу данных.Вот тот же тест bash, что и ранее, но для STDOUT:
Хотя можно обойти эти проблемы, вы неизбежно забудете разработать сценарии вокруг них. Все мы делаем в какой-то момент. Члены вашей команды могут также не понимают / помнить , что этот псевдоним на месте, что в свою очередь создает проблемы для вас , когда они пишут сценарии , которые используют свой псевдоним.
Псевдоним очень похож
ssh
наssh -t
тот случай, когда вы нарушите принцип дизайна наименьшего удивления ; люди будут сталкиваться с проблемами, которых они не ожидают, и могут не понимать, что их вызывает.источник
Escape-символы SSH и передача двоичных файлов
Одно преимущество, которое не было упомянуто в других ответах, состоит в том, что при работе без псевдотерминала экранирующие символы SSH, такие как
~C
, не поддерживаются ; это позволяет программам безопасно передавать двоичные файлы, которые могут содержать эти последовательности.Доказательство концепции
Скопируйте двоичный файл, используя псевдо-терминал:
Скопируйте бинарный файл без использования псевдо-терминала:
Два файла не совпадают:
Тот, который был скопирован с псевдо-терминалом, поврежден:
в то время как другой нет:
Передача файлов по SSH
Это особенно важно для программ, таких как
scp
илиrsync
которые используют SSH для передачи данных. Это подробное описание того, как работает протокол SCP, объясняет, как протокол SCP состоит из смеси текстовых сообщений протокола и данных двоичного файла.OpenSSH помогает защитить вас от себя
Стоит отметить, что даже если этот
-t
флаг используется,ssh
клиент OpenSSH откажется выделять псевдо-терминал, если обнаружит, что егоstdin
поток не является терминалом:Вы по-прежнему можете заставить клиента OpenSSH выделить псевдо-терминал с помощью
-tt
:В любом случае, это (разумно) не волнует, если
stdout
илиstderr
перенаправлены:источник
На удаленном хосте мы имеем дело с этим параметром:
Без судо
И с судо
С sudo мы получаем дополнительный возврат каретки
Решение состоит в том, чтобы отключить перевод новой строки для возврата каретки-новой строки с помощью
stty -onlcr
источник
Подумайте о обратной совместимости.
2 основных режима ssh: интерактивный вход в систему с tty и указанная команда без tty, потому что это были точные возможности
rlogin
иrsh
соответственно. ssh необходимо было предоставить расширенный набор функцийrlogin
/rsh
для успешной замены.Таким образом, значения по умолчанию были определены до рождения ssh. Комбинации типа «Я хочу указать команду и получить tty» должны были быть доступны с новыми опциями. Радуйтесь , что по крайней мере у нас есть этот вариант сейчас, в отличие от , когда мы использовали
rsh
. Мы не обменяли никаких полезных функций на получение зашифрованных соединений. Мы получили бонусы!источник
От
man ssh
:Это позволяет вам получить своего рода «оболочку» на удаленном сервере. Для серверов, которые не предоставляют доступ к оболочке, но разрешают SSH (т. Е. Github является известным примером доступа к SFTP), использование этого флага приведет к тому, что сервер отклонит ваше соединение.
В оболочке также есть все ваши переменные окружения (например
$PATH
), поэтому для выполнения сценариев обычно требуется tty.источник
non-interactive
,interactive
иlogin
.login
является дополнительной характеристикой двух других типов оболочек. Перестановки этих трех параметров определяют, какие файлы получены при входе в систему, что, в свою очередь, влияет на то, как будет инициализироваться среда. (переменные, как вы упоминали)