SSH - неправильное поведение терминала, когда SSH вызывается из цикла `while read` - PullRequest
0 голосов
/ 01 мая 2018

Я пишу сценарий Bash для автоматизации задач на нескольких серверах.

Я подключаюсь к машине Centos 7 через SSH для запуска какого-либо редактора (nano, vi, ...)

ssh -tt centos@... '/bb/Conf edit'

/bb/Conf edit в основном просто vi /bb/conf.yaml.

Когда я запускаю команду SSH из своей оболочки, она работает нормально. Однако, когда та же команда SSH запускается из скрипта Bash внутри цикла while read ...; do, редактор имеет неправильный размер (80x40, я думаю) и, кажется, игнорирует нажимаемые мной клавиши - то есть в nano, Ctrl + x hasn ' ничего не делай. Единственная клавиша, которая работает, это Ctrl + c, которая закрывает соединение.

Я думал, что это что-то, связанное с переменной TERM, согласно это , поэтому я попытался добавить export TERM=xterm или TERM=rxvt к /bb/Conf или к месту, вызывающему SSH. Переменная фактически установлена ​​в целевой среде (я пробовал echo $TERM прямо перед vi). Но терминал по-прежнему плохо себя вел.

Затем я попытался поместить эту единственную команду ssh ... в новый скрипт. При этом редактор работал нормально.

Через некоторое время я обнаружил, что он работает вне цикла while read, но не внутри. Я предполагаю, что редакторы совершают магию stdin / stdout, а затем read как-то ломает это.

Есть ли способ запустить редактор вроде vi или nano из цикла?

(Цель в моем случае - позволить пользователям редактировать файлы на нескольких серверах.)

1 Ответ

0 голосов
/ 01 мая 2018

Это потому, что и read, и ssh читают из одного входного потока. Решение состоит в том, чтобы использовать другой дескриптор файла для цикла чтения:

while IFS= read -r -u3 line; do
    ssh ...
done 3< file

Здесь мы используем дескриптор файла 3 вместо стандартного ввода.


Длинные конвейеры могут быть трудны для чтения и обслуживания, но вы можете использовать пробелы конструктивно: переводы строки разрешены после | и && и ||. Кроме того, в скобках вводится подоболочка, которая содержит произвольный скрипт, поэтому отступы помогают.

while read -u3 line; do
    : do stuff here that needs to read from stdin
done 3< <(
    command 1 of the pipeline |
    command 2 |
    command 3
)

Это чисто и читабельно. Недостатком является то, что он помещает последнюю часть конвейера (цикл while) в первую очередь, поэтому вид кода течет в обратном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...