Comandos remotos SSH: advertencia de enlace bash: edición de línea no habilitada

17

Estoy usando bash 4.3.11 (1) y tengo el siguiente complemento de historial instalado (a través de .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'

Cuando inicio sesión en una sesión interactiva, todo está bien, pero cuando ejecuto comandos remotos a través de, ssh host 'ls -als'por ejemplo, veo el siguiente resultado:

: 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

Cuando modifico el complemento de historial echo -e '\0033\0143'después de cada llamada de enlace, ya no recibo las advertencias, pero mi consola se borra. No es un gran inconveniente, pero sería bueno saber una forma más limpia de suprimir esto para los comandos remotos.

# 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'
Brian
fuente

Respuestas:

28
ssh host 'ls -als'

Cuando le pide a ssh que ejecute un comando en el sistema remoto, ssh normalmente no asigna un PTY (pseudo-TTY) para la sesión remota. Puede ejecutar ssh con -tpara forzarlo a asignar un tty:

ssh -t host 'ls -als'

Si no desea escribir eso todo el tiempo, puede agregar esta línea al archivo ".ssh / config" en su host local:

RequestTTY yes

Alternativamente, puede corregir el archivo ".bashrc" en su sistema remoto para evitar ejecutar comandos que presumen que la sesión es interactiva cuando no lo es. Una forma es incluir los comandos en una prueba de que la sesión tiene un TTY:

if [ -t 1 ]
then
    # standard output is a tty
    # do interactive initialization
fi
Kenster
fuente
1
En realidad, esta respuesta es incorrecta, consulte la respuesta de @ alexander-vorobiev a continuación.
Ahmed Masud
2

Tener una sesión interactiva no es suficiente para bindtrabajar. Por ejemplo, emacs shell proporciona una sesión interactiva que pasa la if [ -t 1 ]prueba, pero no tiene la edición de línea, por lo que cualquier binds en su ~/.bashrcgenerará las advertencias. En cambio, puede verificar si la edición de línea está habilitada haciendo algo como esto (¿hay una manera más simple / mejor?):

if [[ "$(set -o | grep 'emacs\|\bvi\b' | cut -f2 | tr '\n' ':')" != 'off:off:' ]]; then
  echo "line editing is on"
fi
Alexander Vorobiev
fuente
Esta debería ser la respuesta correcta
Ahmed Masud
1
La forma más fácil sería usarlo[[ ${SHELLOPTS} =~ (vi|emacs) ]] && echo 'line-editing on' || echo 'line-editing off'
Ahmed Masud el
1

Ponga los comandos de enlace en una instrucción 'if' que verifique si la sesión bash permite la edición de línea:

if [[ ${SHELLOPTS} =~ (vi|emacs) ]]; then
    bind '"^[[A":history-search-backward'
    bind '"^[[B":history-search-forward'
fi
Jonathan Hartley
fuente
1

Si no hay edición de línea, estos bindcomandos en sí mismos son inofensivos. Suprimir las advertencias:

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

Esto es algo poco elegante, aún así debería funcionar. Otras respuestas no están de acuerdo con la prueba mejor / suficiente. Mi enfoque evita esto. Sin embargo, no escala bien. Los dos comandos por sí solos no deberían hacer una gran diferencia; pero si tuviera más, como docenas, entonces un condicional apropiado probablemente sería mejor.

Kamil Maciorowski
fuente
Buen punto. Tener un voto a favor. :-)
Jonathan Hartley