Benutzerdefinierte Überlappung des Bash-Clientverlaufs

Benutzerdefinierte Überlappung des Bash-Clientverlaufs

Ich schreibe einen Client, um verschiedene Aufgaben auf dem Zimbra-Server über SSH auszuführen, und bin dabei auf ein kleines Problem gestoßen. Hier ist der Code:

#!/bin/bash
set -e
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
export HISTCONTROL=ignoreboth

# History management
if [ -f $HOME/.zmcli_history ]; then
  history -r $HOME/.zmcli_history
else
  touch $HOME/.zmcli_history
  history -r $HOME/.zmcli_history
fi
trap "history -a $HOME/.zmcli_history && echo -e '\nExiting now.\n'" exit

# Styling
yellow='[33m'
bold='[1m'
off='[0m'

echo

# Client
while :; do
  read -ep "$bold${yellow}zimbra_cli[${off}server_domain$bold${yellow}]> $off" comm
  history -s "$comm"
done

HINWEIS: Wenn Sie dieses Skript ausführen, wird die Verlaufsdatei (.zmcli_history) in Ihrem Home-Verzeichnis erstellt.

Alles funktioniert wie vorgesehen und der Verlauf ist vollständig vorhanden, aber oft bleibt ein Teil eines (normalerweise langen) vorherigen Befehls bestehen, wenn ich weiter durch den Verlauf scrolle. Dieser Teil des Befehls fungiert für den Rest der Sitzung als Teil der Eingabeaufforderung, es sei denn, ich drücke STRG+L, wodurch der Bildschirm gelöscht und auf den Normalzustand zurückgesetzt wird. Ich habe viele Beiträge gelesen, die Leuten geholfen haben, die dieses Problem in ihrem Bash-Terminal hatten. Ihr Problem war, dass PS1 falsch formatiert war und Bash die Länge der Eingabeaufforderungszeichenfolge verwechselt hatte. Hier ist es wahrscheinlich etwas Ähnliches, aber diese Lösungen funktionieren nicht, da der Lesebefehl diese Escape-Zeichen nicht wie Echo verwenden kann (\e).

Ich habe einen Weg gefunden, die Farbsequenzen mit wörtlichen Escapezeichen zu verlassen (STRG+V ESCAPE im Vim-Einfügemodus). Die Farben funktionieren also, aber ich stecke bei diesem Verlaufsproblem fest.

Dinge, die ich versucht habe:

  • Befehlsersetzung :: Schreibe und maskiere die Farbcodes so, dass echo -e sie drucken kann, und echoe sie dann im Lesebefehl $(echo -e '\e[33m'). Die Farben werden immer noch angezeigt, aber das hat beim Verlaufsproblem nicht geholfen
  • Hinzufügen von maskierten [ und ] um die Farbcodes
  • die gesamte Eingabeaufforderung mit Farbcodes in einen separaten Echo-Befehl zu setzen, der vor dem Lesebefehl kommt. Der Nachteil ist, dass ich die Formatierung erst nach dem Lesebefehl (in einem anderen Echo) ausschalten kann, was bedeutet, dass die gesamte Eingabeaufforderung und der Befehl fett und farbig sein werden. Wenn ich jetzt STRG+L drücke, wird sogar die Eingabeaufforderung gelöscht und ich habe nur noch den Cursor

Da ich den Verlauf nicht löschen kann, habe ich schließlich versucht, die Farben zu löschen. Aber dann ist es unmöglich, schnell zwischen Befehlen und Ausgabe zu unterscheiden.

Sie können das Problem reproduzieren, indem Sie das Skript starten und 10-15 lange (unverständliche) Befehle eingeben. Versuchen Sie danach, im Verlauf nach oben und unten zu scrollen, und Sie werden sehen, wovon ich spreche.

Kennt jemand eine Möglichkeit, dies zum Laufen zu bringen?

Antwort1

Ihr Skript,wie es ist, ließ mich das Problem nicht reproduzieren. Erst nachdem ich Farben und dergleichen aktiviert hatte, begann Readline verwirrt zu werden. Fürs Protokoll: Ich habe diese Dinge aktiviert mit

# Styling
yellow=$'\e[33m'
bold=$'\e[1m'
off=$'\e[0m'

Und es ist wahr \[und \]nicht helfen, wiesie tun im Falle vonPS1.

Aber dann fand ichdiese Antwort. Es liest

Ich öffnete info readlineund fand:

[…]
Anwendungen können angeben, dass die Eingabeaufforderung Zeichen enthält, die bei der Anzeige keinen physischen Bildschirmplatz beanspruchen, indem sie eine Folge solcher Zeichen mit den speziellen Markierungen RL_PROMPT_START_IGNOREund RL_PROMPT_END_IGNORE(deklariert in ) einklammern readline.h. Dies kann verwendet werden, um terminalspezifische Escape-Sequenzen in Eingabeaufforderungen einzubetten.

Ich habe beispielsweise im Text nach einer Definition gesucht RL_PROMPT_START_IGNOREund Folgendes gefunden:RL_PROMPT_END_IGNOREreadline.h

/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE  '\001'
#define RL_PROMPT_END_IGNORE    '\002'

Dies führte mich zu Folgendem:

# Styling
yellow=$'\1\e[33m\2'
bold=$'\1\e[1m\2'
off=$'\1\e[0m\2'

Es funktioniert einwandfrei.

verwandte Informationen