In dem, was Sie fragen, spielen verschiedene Aspekte eine Rolle.
Erstens definiert bash keine Farben. Tatsächlich ahnt bash gar nicht, dass es überhaupt Farben gibt. Es weiß nur, dass Sie es angewiesen haben, die Zeichen auszugeben \033[0;36m
. Ihr Terminal-Emulator (xterm, gnome-terminal, was auch immer) empfängt diese Zeichen und versteht "Ich muss mit der Ausgabe in Cyan beginnen".
Somit ist es Ihr Terminal-Emulator, der Farben versteht. Ihr Terminal-Emulator versteht, dass \033[0;36m
es sich um Cyan handelt, aber ein anderer Terminal-Emulator verwendet möglicherweise einen völlig anderen Zeichensatz für Cyan (obwohl kein vernünftiger Terminal-Emulator den Standard zur Schau stellt und dies tut). Dies ist der Grund für tput
. Wenn Sie ausführen tput setaf 6
, werden tput
die Escape-Codes Ihres Terminals für die Farbe 6 (Cyan) nachgeschlagen und dieser Escape-Code ausgegeben.
( Weitere Informationen zu Codes finden Sie in dieser Frage.tput setaf
)
Nun zurück zur Bash. Wie Sie vielleicht bemerkt haben, verwende ich, wenn ich mich auf die Farbe Cyan beziehe \033[0;36m
, nicht \[\033[0;36m\]
. Die eckigen Klammern fehlen. Der Zweck der eckigen Klammern ist, dass bash bei Verwendung von Escape-Codes (Farben) in der Eingabeaufforderung wissen muss, welche Zeichen nicht gedruckt werden (Breite Null, zeigt eigentlich nichts an). So schließen Sie nicht druckbare Zeichen in ein \[
\]
. Wenn Sie diese Zeichen entfernen, scheint zunächst alles in Ordnung zu sein, aber wenn Ihr Befehl die Breite des Terminals überschreitet, werden Sie auf jede Art von Verrücktheit stoßen. Dies liegt daran, dass bash während der Eingabe wissen muss, wann der Befehl in die nächste Zeile umgebrochen werden soll. Dazu berechnet es die Breite der Eingabeaufforderung und anschließend die Breite der von Ihnen eingegebenen Zeichen.
Noch eine Notiz, ungefähr tput
. CYAN="\[\033[0;36m\]"
ist nicht dasselbe wie CYAN="$(tput setaf 6)"
. Wie wir gerade besprochen haben, sind die eckigen Klammern relevant für Bash und geben tput
nur die Terminal-Escape-Codes aus.
Da eckige Klammern normalerweise nur in der Eingabeaufforderung relevant sind, sollten Sie sie nicht verwenden, wenn Sie Farben in der Ausgabe eines Skripts oder Ähnlichem verwenden. Das heißt, wenn Sie Farben für mehr als nur Eingabeaufforderungen verwenden möchten, müssen Sie mehrere Variablen definieren. Eine mit eckigen Klammern für die Verwendung in der Eingabeaufforderung und eine ohne für alles andere. Sie können die eckigen Klammern jedoch auch jedes Mal manuell hinzufügen, wenn Sie auf eine Farbe in der Eingabeaufforderung verweisen.
So lange die Rede ist, möchten Sie wahrscheinlich Folgendes definieren:
local CYAN="$(tput setaf 6)" # OR CYAN="\033[0;36m"
local LIGHT_CYAN="$CYAN$(tput bold)" # OR LIGHT_CYAN="\033[1;36m"
local PROMPT_CYAN="\[$CYAN\]"
local PROMPT_LIGHT_CYAN="\[$LIGHT_CYAN\]"
\e[1;30m
zum Beispiel technisch nicht grau darstellen, sondern der Farbschlitz, der normalerweise von einem Terminal als grau angezeigt wird. Terminalemulatoren können die tatsächlichen Anzeigefarben frei ändern und sind häufig eine vom Benutzer konfigurierbare Option.