Commandes SSH distantes - Avertissement de liaison bash: modification de ligne non activée

17

J'utilise bash 4.3.11 (1) et le plugin d'historique suivant est installé (via .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'

Lorsque je me connecte à une session interactive, tout va bien, mais lorsque j'exécute des commandes à distance via, ssh host 'ls -als'par exemple, je vois la sortie suivante:

: 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

Lorsque je modifie le plugin d'historique avec echo -e '\0033\0143'après chaque appel de liaison, je ne reçois plus les avertissements mais ma console est effacée. Ce n'est pas un gros inconvénient, mais ce serait bien de connaître un moyen plus propre de supprimer cela pour les commandes à distance.

# 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
la source

Réponses:

28
ssh host 'ls -als'

Lorsque vous demandez à ssh d'exécuter une commande sur le système distant, ssh n'alloue normalement pas de PTY (pseudo-TTY) pour la session distante. Vous pouvez exécuter ssh avec -tpour le forcer à allouer un tty:

ssh -t host 'ls -als'

Si vous ne voulez pas taper cela tout le temps, vous pouvez ajouter cette ligne au fichier ".ssh / config" sur votre hôte local:

RequestTTY yes

Alternativement, vous pouvez corriger le fichier ".bashrc" sur votre système distant pour éviter d'exécuter des commandes qui supposent que la session est interactive lorsqu'elle ne l'est pas. Une façon consiste à inclure les commandes dans un test que la session a un ATS:

if [ -t 1 ]
then
    # standard output is a tty
    # do interactive initialization
fi
Kenster
la source
1
En fait, cette réponse est incorrecte, voir la réponse de @ alexander-vorobiev ci-dessous.
Ahmed Masud
2

Avoir une session interactive ne suffit pas pour bindtravailler. Par exemple, le shell emacs fournit une session interactive qui réussit le if [ -t 1 ]test mais il n'a pas d'édition de ligne, donc tout binds dans votre ~/.bashrcgénérera les avertissements. Au lieu de cela, vous pouvez vérifier si la modification de ligne est activée en faisant quelque chose comme ceci (y a-t-il un moyen plus simple / meilleur?):

if [[ "$(set -o | grep 'emacs\|\bvi\b' | cut -f2 | tr '\n' ':')" != 'off:off:' ]]; then
  echo "line editing is on"
fi
Alexander Vorobiev
la source
Cela devrait être la bonne réponse
Ahmed Masud
1
La façon la plus simple serait d'utiliser[[ ${SHELLOPTS} =~ (vi|emacs) ]] && echo 'line-editing on' || echo 'line-editing off'
Ahmed Masud
1

Mettez les commandes de liaison dans une instruction 'if' qui vérifie si la session bash autorise l'édition de ligne:

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

S'il n'y a pas d'édition de ligne, ces bindcommandes elles-mêmes sont inoffensives. Supprimez les avertissements:

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

C'est un peu inélégant, mais cela devrait encore fonctionner. D'autres réponses ne concordent pas sur le meilleur test / suffisant. Mon approche contourne cela. Cela ne se modifie cependant pas bien. Les deux commandes seules ne devraient pas faire une grande différence; mais si vous en aviez plus, comme des dizaines, alors un bon conditionnel serait probablement mieux.

Kamil Maciorowski
la source
Bon point. Ayez un vote positif. :-)
Jonathan Hartley