Яка користь від не розподілу терміналу в ssh?


66

Раз у раз я буду робити щось подібне

ssh user@host sudo thing

і мені нагадується, що ssh не виділяє псевдо-tty за замовчуванням. Чому це не так? Які переваги я б втратити , якщо я псевдонімами , sshщоб ssh -t?


1
> Мені нагадують, що ssh не виділяє psuedo-tty Що відбувається? Це збагатило б питання, щоб зрозуміти, у чому проблема.
Повітря

5
@Air Немає проблеми, яку я намагався виправити. Був вибір, як реалізується ssh, що я намагався зрозуміти. Питання дуже чітке, і відповідь Ендрю Б відповідає на це питання. Відповідь можна підсумувати так: біг ssh -tзавжди поганий, оскільки це може спричинити ламання деяких команд дивними способами. Тоді як запуск команди, для якої потрібен PTY без одного, призводить до явного повідомлення про помилку, що вам потрібен термінал.
Час. Оуенс

Відповіді:


73

Основна відмінність - поняття інтерактивності . Це схоже на виконання команд локально всередині скрипту, порівняно з тим, що самостійно їх вводити. Це відрізняється тим, що віддалена команда повинна вибрати типовий, а неінтерактивна - найбезпечніша. (і, як правило, найчесніший)

STDIN

  • Якщо PTY призначений, програми можуть виявити це і знати, що безпечно запросити користувача на додатковий ввід, не порушуючи нічого. Існує багато програм, які пропускають крок запрошення користувача на введення, якщо немає терміналу, і це добре. Це може спричинити зависання сценаріїв без необхідності в іншому випадку.
  • Ваш вхід буде відправлений на віддалений сервер протягом тривалості команди. Сюди входять контрольні послідовності. Хоча Ctrl-cперерва зазвичай спричиняє негайне розрив циклу в команді ssh, керовані послідовності будуть надіслані на віддалений сервер. Це призводить до необхідності "удару" натисканням клавіші, щоб переконатися, що воно надходить, коли управління покидає команду ssh, але до початку наступної команди ssh.

Я б застерігсь від використання ssh -tв сценаріях без догляду, таких як крони. Неінтерактивна оболонка, яка просить віддалену команду поводитись в інтерактивному режимі для введення, задає всілякі проблеми.

Ви також можете перевірити наявність терміналу у власних скриптах оболонки. Для тестування STDIN з новішими версіями bash:

# fd 0 is STDIN
[ -t 0 ]; echo $?

ВИСТАВКА

  • Коли альясінг sshдо ssh -t, ви можете очікувати , щоб отримати додатковий повернення каретки в кінцях вашої лінії. Це може бути вам не видно, але воно є; він відображатиметься так, як ^Mколи cat -e. Потім потрібно витратити додаткові зусилля на те, щоб цей код управління не присвоювався вашим змінним, особливо якщо ви збираєтеся вставити цей вихід у базу даних.
  • Існує також ризик, що програми припускають, що вони можуть надати невідповідний для переадресації файл. Зазвичай, якщо ви перенаправляєте STDOUT на файл, програма визнає, що ваш STDOUT не є терміналом і опускає будь-які кольорові коди. Якщо переадресація STDOUT відбувається з виводу ssh-клієнта і є PTY, пов'язаний з віддаленим кінцем клієнта, віддалені програми не можуть зробити такого розрізнення, і ви потрапите в термінал сміття у вихідному файлі. Перенаправлення виводу на файл на віддаленому кінці з'єднання все одно має працювати, як очікувалося.

Ось такий самий баш-тест, що і раніше, але для STDOUT:

# fd 1 is STDOUT
[ -t 1 ]; echo $?

Незважаючи на те, що можна вирішити ці проблеми, ви неминуче забудете розробити сценарії навколо них. Усі ми робимо в якийсь момент. Члени вашої команди можуть також не усвідомлювати / пам’ятати, що цей псевдонім є на місці, що, у свою чергу, створить для вас проблеми, коли вони пишуть сценарії, які використовують ваш псевдонім.

Aliase sshto ssh -t- це дуже випадок, коли ви порушите принцип дизайну як мінімум здивування ; люди будуть стикатися з проблемами, яких вони не очікують, і можуть не зрозуміти, що їх викликає.


9
Майже складається враження, що я працював над командою, яка зробила це ...
Ендрю Б

Що стосується цієї відповіді, це чудово. Але питання мало ширший обсяг, по суті бажаючи дізнатися ВСІ відмінності (чого очікувати). Додаткова інформація: На рівні процесу -T ПЕРШЕ виділить tty, а потім запустить оболонку (попутно, джерело / etc / profile та ~ / .bash_profile), а потім запустить команду. Без -t, ssh буде ВСТАВИТИ різні файли env (/etc/bash.bashrc, потім ~ / .bashrc), а потім запустить вашу команду. Це означає, що ви можете бачити дуже різну поведінку в кожній: коротше $ PATH, можливо, помилка "unry" помилка, оскільки ENV вар, який ви припускали, немає ...
Scott Prive

@Crossfit Ми обговорили тему оболонок для входу проти інших у коментарях іншої відповіді, але ми не вдалися до вичерпного розбору екологічних відмінностей, оскільки ОП вже розглядала питання, яке відповідає їх конкретним потребам. Будь ласка, не соромтеся додати детальну інформацію про те, де ви бачите місця, щоб це зробити, оскільки це може допомогти іншим, хто стикається з цим питанням.
Андрій Б

33

Символи втечі SSH та передача бінарних файлів

Одним з переваг , які були згадані в інших відповідях є те , що при роботі без псевдо-терміналу , то SSH уникнути символів , такі як ~Cє не підтримує ; це забезпечує безпеку програм для передачі бінарних файлів, які можуть містити ці послідовності.

Доказ концепції

Скопіюйте двійковий файл за допомогою псевдотерміналу:

$ ssh -t anthony@remote_host 'cat /usr/bin/free' > ~/free
Connection to remote_host closed.

Скопіюйте двійковий файл без використання псевдотерміналу:

$ ssh anthony@remote_host 'cat /usr/bin/free' > ~/free2

Два файли не однакові:

$ diff ~/free*
Binary files /home/anthony/free and /home/anthony/free2 differ

Той, який був скопійований псевдотерміналом, пошкоджений:

$ chmod +x ~/free*
$ ./free
Segmentation fault

а інший не:

$ ./free2
             total       used       free     shared    buffers     cached
Mem:       2065496    1980876      84620          0      48264    1502444
-/+ buffers/cache:     430168    1635328
Swap:      4128760        112    4128648

Передача файлів через SSH

Це особливо важливо для таких програм, як 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:

$ echo testing | ssh -tt anthony@remote_host 'echo $TERM'
xterm

У будь-якому випадку, він (розумно) не хвилює , якщо stdoutабо stderrперенаправляються:

$ ssh -t anthony@remote_host 'echo $TERM' >| ssh_output
Connection to remote_host closed.

2
Це був дуже цікавий момент, який я не розглядав, дякую, що додав цю відповідь!
Дженні Д

4

На віддаленому хості ми маємо робити це налаштування:

/etc/sudoers
...
Defaults requiretty

Без судо

$ ssh -T user@host echo -e 'foo\\nbar' | cat -e
foo$
bar$

І з судо

$ ssh -T user@host sudo echo -e 'foo\\nbar' | cat -e
sudo: sorry, you must have a tty to run sudo

З судо ми отримуємо додаткове повернення вагона

$ ssh -t user@host sudo echo -e 'foo\\nbar' | cat -e
foo^M$
      bar^M$
            Connection to localhost closed.

Рішення полягає в тому, щоб вимкнути переклад нової лінії на перевезення з нової каретки за допомогоюstty -onlcr

$ ssh -t user@host stty -onlcr\; sudo echo -e 'foo\\nbar' | cat -e
foo$
    bar$
        Connection to localhost closed.

1
Приємно, але вихід з відступом /: Чи трапляється ви знати, чи можете ви перевезти авто-перевезення - повернути його (схоже на unix)?
Буп

1

Подумайте про зворотну сумісність.

Два основні режими ssh - це інтерактивний вхід з tty, і вказана команда без tty, оскільки це були точні можливості rloginта rshвідповідно. ssh, необхідний для надання набору rlogin/ rshфункцій, щоб досягти успіху в якості заміни.

Тож про дефолти було вирішено до появи ssh. До комбінацій на кшталт "Я хочу вказати команду та отримати tty" потрібно було отримати нові параметри. Будьте раді, що принаймні у нас є такий варіант зараз, на відміну від того, коли ми користувалися rsh. Ми не торгували корисними функціями, щоб отримати зашифровані з'єднання. Ми отримали бонусні функції!


0

Від man ssh:

 -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 для роботи.


1
Це не дає відповіді на запитання. Я вже знаю, як виділити псевдо-тти. Я хочу знати, чому я не повинен завжди завжди виділяти його.
Час. Оуенс

1
@ Chas.Owens Оскільки, як я зазначив у відповіді, деякі SSH-сервери не дозволяють отримати доступ tty, і це перерве з'єднання, якщо ви запитаєте його від сервера.
Натан С

5
Я думаю, що ви можете заплутати якусь свою термінологію. Це не оболонка просто тому, що з нею асоціюється PTY. Є три загальних типу оболонки: non-interactive, interactiveі login. loginє додатковою характеристикою для двох інших типів оболонок. Перестановки цих трьох визначають, які файли отримуються при вході в систему, що, в свою чергу, впливає на те, як середовище буде ініціалізовано. (змінні, як ви згадували)
Андрій Б

3
@AndrewB Ти маєш рацію ... Я теж щось дізнався з цього питання. :)
Натан C
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.