Remote-SSH-Befehle - Bash-Bind-Warnung: Die Zeilenbearbeitung ist nicht aktiviert

17

Ich verwende bash 4.3.11 (1) und habe das folgende History-Plugin installiert (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'

Wenn ich mich bei einer interaktiven Sitzung anmelde, ist alles in Ordnung, aber wenn ich ssh host 'ls -als'beispielsweise Remotebefehle über ausführe , wird die folgende Ausgabe angezeigt:

: 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

Wenn ich das Verlaufs-Plugin echo -e '\0033\0143'nach jedem Bind-Aufruf ändere, werden keine Warnungen mehr angezeigt, aber meine Konsole wird gelöscht. Kein großer Nachteil, aber es wäre schön, einen saubereren Weg zu kennen, um dies für Remote-Befehle zu unterdrücken.

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

Antworten:

28
ssh host 'ls -als'

Wenn Sie ssh auffordern, einen Befehl auf dem Remote-System auszuführen, weist ssh der Remote-Sitzung normalerweise kein PTY (Pseudo-TTY) zu. Sie können ssh mit ausführen -t, um die Zuweisung einer tty zu erzwingen:

ssh -t host 'ls -als'

Wenn Sie dies nicht ständig eingeben möchten, können Sie diese Zeile zur Datei ".ssh / config" auf Ihrem lokalen Host hinzufügen:

RequestTTY yes

Alternativ können Sie die ".bashrc" -Datei auf Ihrem Remote-System korrigieren, um zu vermeiden, dass Befehle ausgeführt werden, bei denen angenommen wird, dass die Sitzung interaktiv ist, wenn dies nicht der Fall ist. Eine Möglichkeit besteht darin, die Befehle in einen Test einzuschließen, bei dem die Sitzung ein TTY hat:

if [ -t 1 ]
then
    # standard output is a tty
    # do interactive initialization
fi
Kenster
quelle
1
Eigentlich ist diese Antwort falsch, siehe @ alexander-vorobievs Antwort unten.
Ahmed Masud
2

Eine interaktive Sitzung reicht nicht aus, um bindzu arbeiten. Zum Beispiel bietet die emacs-Shell eine interaktive Sitzung, die den if [ -t 1 ]Test besteht, aber keine Zeilenbearbeitung hat, sodass alle binds in Ihnen ~/.bashrcdie Warnungen generieren. Stattdessen können Sie folgendermaßen überprüfen, ob die Zeilenbearbeitung aktiviert ist (gibt es einen einfacheren / besseren Weg?):

if [[ "$(set -o | grep 'emacs\|\bvi\b' | cut -f2 | tr '\n' ':')" != 'off:off:' ]]; then
  echo "line editing is on"
fi
Alexander Vorobiev
quelle
Dies sollte die richtige Antwort sein
Ahmed Masud
1
Der einfachere Weg wäre zu verwenden[[ ${SHELLOPTS} =~ (vi|emacs) ]] && echo 'line-editing on' || echo 'line-editing off'
Ahmed Masud
1

Fügen Sie die Bindebefehle in eine 'if'-Anweisung ein, die prüft, ob die Bash-Sitzung die Bearbeitung von Zeilen zulässt:

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

Wenn keine Zeilenbearbeitung erfolgt, sind diese bindBefehle selbst harmlos. Unterdrücken Sie die Warnungen:

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

Das ist etwas unelegant, sollte aber trotzdem funktionieren. Andere Antworten stimmen nicht mit dem besten / ausreichenden Test überein. Mein Ansatz umgeht dies. Es ist jedoch nicht gut skalierbar. Die beiden Befehle alleine sollten keinen großen Unterschied machen. aber wenn Sie mehr hätten, wie Dutzende, dann wäre eine richtige Bedingung wahrscheinlich besser.

Kamil Maciorowski
quelle
Guter Punkt. Habe eine positive Stimme. :-)
Jonathan Hartley