Удаленные команды SSH - предупреждение bash bind: редактирование строки не включено

17

Я использую bash 4.3.11 (1) и у меня установлен следующий плагин истории (через .bash_it ):

# enter a few characters and press UpArrow/DownArrow
# to search backwards/forwards through the history
bind '"^[[A":history-search-backward'
bind '"^[[B":history-search-forward'

Когда я вхожу в интерактивный сеанс, все хорошо, но когда я запускаю удаленные команды, ssh host 'ls -als'например, через , я вижу следующий вывод:

: ssh host 'ls -als'
/home/ubuntu/.bash_it/plugins/enabled/history.plugin.bash: line 3: bind: warning: line editing not enabled
/home/ubuntu/.bash_it/plugins/enabled/history.plugin.bash: line 4: bind: warning: line editing not enabled

Когда я изменяю плагин истории echo -e '\0033\0143'после каждого связывающего вызова, я больше не получаю предупреждения, но моя консоль очищается. Не большой недостаток, но было бы неплохо знать более чистый способ подавления этого для удаленных команд.

# Works, but annoyingly clears console
# enter a few characters and press UpArrow/DownArrow
# to search backwards/forwards through the history
bind '"^[[A":history-search-backward'
echo -e '\0033\0143'
bind '"^[[B":history-search-forward'
echo -e '\0033\0143'
Брайан
источник

Ответы:

28
ssh host 'ls -als'

Когда вы просите ssh выполнить команду в удаленной системе, ssh обычно не выделяет PTY (псевдо-TTY) для удаленного сеанса. Вы можете запустить ssh, -tчтобы заставить его выделить tty:

ssh -t host 'ls -als'

Если вы не хотите вводить это все время, вы можете добавить эту строку в файл ".ssh / config" на вашем локальном хосте:

RequestTTY yes

Кроме того, вы можете исправить файл «.bashrc» в удаленной системе, чтобы избежать запуска команд, которые предполагают, что сеанс является интерактивным, когда это не так. Один из способов заключается в том, чтобы заключить команды в тест, что у сеанса есть TTY:

if [ -t 1 ]
then
    # standard output is a tty
    # do interactive initialization
fi
Kenster
источник
1
На самом деле этот ответ неверен, см. Ответ @ alexander-vorobiev ниже.
Ахмед Масуд
2

bindДля работы недостаточно иметь интерактивный сеанс . Например, оболочка emacs предоставляет интерактивный сеанс, который проходит if [ -t 1 ]тест, но у него нет редактирования строки, поэтому любые bindваши сообщения ~/.bashrcбудут генерировать предупреждения. Вместо этого вы можете проверить, включено ли редактирование строки, выполнив что-то вроде этого (есть ли более простой / лучший способ?):

if [[ "$(set -o | grep 'emacs\|\bvi\b' | cut -f2 | tr '\n' ':')" != 'off:off:' ]]; then
  echo "line editing is on"
fi
Александр Воробьев
источник
Это должен быть правильный ответ
Ахмед Масуд
1
Более простой способ будет использовать[[ ${SHELLOPTS} =~ (vi|emacs) ]] && echo 'line-editing on' || echo 'line-editing off'
Ахмед Масуд
1

Поместите команды связывания в оператор if, который проверяет, позволяет ли сеанс bash редактировать строки:

if [[ ${SHELLOPTS} =~ (vi|emacs) ]]; then
    bind '"^[[A":history-search-backward'
    bind '"^[[B":history-search-forward'
fi
Джонатан Хартли
источник
1

Если нет редактирования строки, bindсами эти команды безвредны. Подавить предупреждения:

bind '"^[[A":history-search-backward' 2>/dev/null
bind '"^[[B":history-search-forward'  2>/dev/null

Это несколько не элегантно, все же это должно работать. Другие ответы не согласны с лучшим / достаточным тестом. Мой подход обходит это. Это не хорошо масштабируется, хотя. Две эти команды не должны иметь большого значения; но если бы у вас было больше, например, десятки, то правильное условие, вероятно, было бы лучше.

Камил Мачоровски
источник
Хорошая точка зрения. Имейте upvote. :-)
Джонатан Хартли