Віддалені команди SSH - попередження про прив'язку баш: редагування рядків не ввімкнено


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

1
Насправді ця відповідь невірна, див. Відповідь @ alexander-vorobiev нижче.
Ахмед Масуд

2

Інтерактивний сеанс недостатньо для bindроботи. Наприклад, оболонка emacs забезпечує інтерактивний сеанс, який проходить if [ -t 1 ]тест, але він не має редагування рядків, тому будь-який binds у вашому ~/.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

Покладіть команди прив’язки до оператора "якщо", який перевіряє, чи дозволяє сеанс 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

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


Гарна думка. Майте нагороду. :-)
Джонатан Хартлі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.