Comandi SSH remoti - avviso bash bind: modifica della linea non abilitata


17

Sto usando bash 4.3.11 (1) e ho installato il seguente plugin di cronologia (tramite .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'

Quando accedo a una sessione interattiva va tutto bene, ma quando eseguo comandi remoti tramite, ssh host 'ls -als'ad esempio, vedo il seguente output:

: 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

Quando modifico il plug-in della cronologia con echo -e '\0033\0143'dopo ogni chiamata di bind non ricevo più gli avvisi ma la mia console viene cancellata. Non è un grosso svantaggio, ma sarebbe bello conoscere un modo più pulito di sopprimerlo per i comandi remoti.

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

Risposte:


28
ssh host 'ls -als'

Quando chiedi a ssh di eseguire un comando sul sistema remoto, ssh normalmente non alloca un PTY (pseudo-TTY) per la sessione remota. Puoi eseguire ssh con -tper forzarlo ad allocare un tty:

ssh -t host 'ls -als'

Se non vuoi scriverlo sempre, puoi aggiungere questa riga al file ".ssh / config" sul tuo host locale:

RequestTTY yes

In alternativa, è possibile correggere il file ".bashrc" sul sistema remoto per evitare di eseguire comandi che presumono che la sessione sia interattiva quando non lo è. Un modo è racchiudere i comandi in un test che la sessione ha un TTY:

if [ -t 1 ]
then
    # standard output is a tty
    # do interactive initialization
fi

1
In realtà questa risposta non è corretta, vedi la risposta di @ alexander-vorobiev di seguito.
Ahmed Masud,

2

Avere una sessione interattiva non è sufficiente per bindfunzionare. Per esempio emacs shell fornisce una sessione interattiva che passa la if [ -t 1 ]prova ma non ha la linea di editing in modo che qualsiasi binds nel vostro ~/.bashrcgenererà gli avvertimenti. Invece, puoi verificare se la modifica della linea è abilitata facendo qualcosa del genere (esiste un modo più semplice / migliore?):

if [[ "$(set -o | grep 'emacs\|\bvi\b' | cut -f2 | tr '\n' ':')" != 'off:off:' ]]; then
  echo "line editing is on"
fi

Questa dovrebbe essere la risposta corretta
Ahmed Masud,

1
Il modo più semplice sarebbe usare[[ ${SHELLOPTS} =~ (vi|emacs) ]] && echo 'line-editing on' || echo 'line-editing off'
Ahmed Masud,

1

Inserisci i comandi bind in un'istruzione 'if' che controlla se la sessione bash consente la modifica della riga:

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

1

Se non è possibile modificare le righe, questi bindcomandi stessi sono innocui. Elimina gli avvisi:

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

Questo è in qualche modo inelegante, tuttavia dovrebbe funzionare. Altre risposte non concordano sul test migliore / sufficiente. Il mio approccio elude questo. Non si adatta bene però. I due comandi da soli non dovrebbero fare una grande differenza; ma se ne avessi di più, come dozzine, probabilmente un condizionale adeguato sarebbe meglio.


Buon punto. Avere un voto. :-)
Jonathan Hartley,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.