Farbe im Terminal braucht man zwar nicht unbedingt, schön sieht es aber trotzdem aus – und macht nur wenig Aufwand.
Sieht man sich die Ausgabe der gebräuchlichen Linux-Kommandos an, glänzen sie durch eine Eigenschaft: Einfachheit. Nichts blinkt, wackelt oder macht Geräusche – Information pur ohne störendes Drumherum. In der heutigen Welt, in der jedes Gerät oder offener Reiter im Webbrowser mit einem Piepton um Aufmerksamkeit bettelt, führt diese für Neueinsteiger eher anachronistisch anmutende Vorgehensweise zu einem zielgerichteten Arbeiten, bei dem man ein Problem mit voller Konzentration lösen kann. Einfach traumhaft.
Warum Farbe?
Wenn alles so perfekt ist, wieso kommt dann hier Farbe ins Spiel? Farbe dient dazu, Dinge hervorzuheben und unsere Aufmerksamkeit an einen bestimmten Punkt oder auf ein Faktum zu lenken. Im Folgenden sehen wir uns an, wie wir die Ausgabe auf der Kommandozeile mit etwas Farbe aufpeppen. Dabei gilt es zu berücksichtigen, dass die tatsächliche Darstellung der Ausgabe vom Terminal, dessen Größe, den genutzten Fonts und sonstigen Einstellungen abhängt. Schließlich soll die Ausgabe ja auch lesbar bleiben.
Ohne Farbe müssen sich weder Entwickler noch Programm um die Eigenschaften des gerade genutzten Terminals und dessen Eigenschaften kümmern. Niemand muss wissen, wie das Terminal des Anwenders eingestellt ist und welche Ausgabe das Programm verwendet – beispielsweise, ob es eine schlichte Anzeige im Terminal ist, eine Umleitung in eine Datei oder eine Weiterverarbeitung via Pipe. Merke: Farbe steigert die Komplexität.
Im Terminal
In der Shell steuern ANSI-Escape-Sequenzen den Cursor im Terminal. Mit ihnen lassen sich nicht nur Farben einstellen, sondern auch Textkorrekturen vornehmen und die Schreibmarke steuern. In diesem Artikel liegt der Fokus auf der farbigen Ausgabe, mit Änderung der Vorder- und Hintergrundfarbe plus zusätzlichen Hervorhebungen wie Fettdruck und Unterstreichung.
Zunächst gilt es zu klären, was das gerade verwendete Terminal kann. Ein guter, aber nicht perfekter Indikator dafür ist die Umgebungsvariable TERM. Sie enthält nicht etwa den Namen der Shell oder der Terminalemulation, sondern die Kategorie des Terminals. Mit dieser Kategorie sind Eigenschaften verbunden, die sich im Verzeichnis /lib/terminfo nachlesen lassen.
Mithilfe des echo-Kommandos ermitteln Sie, wie in der ersten Zeile von Listing 1 gezeigt, den Wert der Variablen TERM. An der Ausgabe erkennen Sie, dass der Aufruf im Beispiel in einer Terminalemulation stattfand, die die Eigenschaften eines Xterms mit 256 Farben besitzt. Die aktuellen Einstellungen im Terminal liefert das Kommando infocmp aus dem Paket ncurses-bin [1]. Als Parameter übergeben Sie ihm den Inhalt von TERM (Zeile 3) und erhalten eine Ausgabe, die alle Einstellungen des Terminals in Form von kryptisch wirkenden Abkürzungen und Werten offenlegt.
Listing 1
Terminal-Infos (Ausschnitt)
$ echo $TERM xterm-256color $ infocmp xterm-256color # Reconstructed via infocmp from file: /lib/terminfo/x/xterm-256color xterm-256color|xterm with 256 colors, am, bce, ccc, km, mc5i, mir, msgr, npc, xenl, colors#0x100, cols#80, it#8, lines#24, pairs#0x10000, acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, civis=\E[?25l, clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=\r, csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=\n, cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, [...] $
Die einzelnen Werte für Farben und Hervorhebungen nennt ein Artikel aus LU 08/2007 [2], eine Kurzfassung mit weiteren Beispielen enthält ein Post [3] von Ifenna auf DEV.to. Wer es technisch ganz detailliert nachlesen möchte, vertieft sich in das Bash Prompt Howto [4].
So schön das mit den Farbwerten ist, es bietet reichlich Potenzial für Fehler durch Buchstaben- und Zahlendreher bei den Farbwerten. Dass das Ganze auch einfacher geht, zeigt das Kommando tput [5]. Statt der kryptischen Farbwerte akzeptiert es Ziffern (Tabelle “Farbwerte”) oder Kürzel (Tabelle “Texteffekte”), die es dann in die entsprechenden ANSI-Steuercodes übersetzt.
|
Wert |
Farbe |
|---|---|
|
|
Schwarz |
|
|
Rot |
|
|
Grün |
|
|
Gelb |
|
|
Blau |
|
|
Magenta |
|
|
Cyan |
|
|
Weiß |
|
|
unbenutzt |
|
|
Zurücksetzen auf die Standardfarbe |
|
Kürzel |
Bedeutung |
|---|---|
|
|
Fettschrift (Anfang) |
|
|
Unterstreichung (Anfang) |
|
|
Unterstreichung (Ende) |
|
|
Invertierung (Anfang) |
|
|
Blinkender Text (Anfang) |
|
|
Unsichtbarer Text (Anfang) |
|
|
Standout-Modus (Anfang) |
|
|
Standout-Modus (Ende) |
|
|
Alle Attribute deaktivieren |
|
|
Vordergrundfarbe setzen |
|
|
Hintergrundfarbe setzen |
Abbildung 1 zeigt eine Textausgabe via Tput in Magenta und Fettdruck. Zunächst aktiviert der Aufruf tput bold die Fettung, dann schaltet das Kommando tput setaf 5 auf die farbige Textdarstellung um. Der folgende Echo-Befehl gibt den Text entsprechend aus. Zu guter Letzt setzt tput sgr0 alle Attribute wieder auf den Originalzustand zurück.
Was zur Orientierung nicht fehlen darf, ist ein Farbspektrum. Listing 2 erzeugt es mithilfe eines Shell-Skripts mit zwei ineinander verschachtelten For-Schleifen [5]. Abbildung 2 zeigt, wie das im Terminal aussieht.
Listing 2
Farben testen
#!/bin/bash
for fg_col in {0..7}; do # Werte 0 bis 7 ...
set_foregrnd=$(tput setaf $fg_col) # ... als Vordergrundfarbe
for bg_col in {0..7}; do # Werte 0 bis 7 ...
set_bkgrnd=$(tput setab $bg_col) # ... als Hintergrundfarbe
echo -n $set_bkgrnd$set_foregrnd # Farbkombi aktivieren
printf ' F:%s B:%s ' $fg_col $bg_col # Text ausgeben
done
echo $(tput sgr0) # Farben zurücksetzen
done
Wollen Sie eine solche Ausgabe nicht selbst erzeugen, sondern lieber auf etwas Bestehendes zurückgreifen, greifen Sie zum Werkzeug Colortest [6]. Es malt Farbspektren aus 8, 16 oder 256 Farben in beeindruckender Schönheit (Abbildung 3).
Mit Python
Was in der Bash gelingt, klappt auf ähnliche Art und Weise auch mit Programmiersprachen wie Python. Im ersten Schritt greifen Sie dabei wieder auf ANSI-Escape-Sequenzen zurück (siehe Blogpost von Li Haoyi [7]). Der dafür notwendige Programmcode ist recht übersichtlich [8], Listing 3 zeigt ihn in angepasster Form.
Die Zeilen 2 bis 11 definieren zunächst ein Dictionary namens basicColorSet, das die Namen der Farben als Schlüssel verwendet. Zu jedem Schlüssel gehört ein entsprechender Farbwert als Zeichenkette. Den Code zum Zurücksetzen der Farbe legt Zeile 14 fest. Eine For-Schleife in den Zeilen 17 und 18 durchläuft das Dictionary und gibt den Namen der Farbe entsprechend koloriert aus. Zeile 21 setzt schließlich alle Farbeinstellungen mithilfe des zuvor definierten Reset-Codes wieder zurück. Abbildung 4 zeigt die Ausgabe nach dem Aufruf des Python-Skripts.
Listing 3
ANSI-Escape-Sequenzen
# Farben festlegen
basicColorSet = {
"schwarz": "\u001b[30m",
"rot": "\u001b[31m",
"grün": "\u001b[32m",
"gelb": "\u001b[33m",
"blau": "\u001b[34m",
"pink": "\u001b[35m",
"hellblau": "\u001b[36m",
"weiss": "\u001b[37m"
}
# Code zum Zurücksetzen der Farbeigenschaften
resetCode = "\u001b[0m"
# Text in der jeweiligen Farbe ausgeben
for item in basicColorSet:
print ("%s %s" % (basicColorSet[item],item))
# Farbeinstellungen zurücksetzen
print (resetCode)

Abbildung 4: Das Ergebnis des Aufrufs des Codes aus Listing 3.
Für Listing 3 gilt dasselbe wie für Listing 2: Wenn die ANSI-Escape-Sequenzen nicht stimmen, kommt im besten Fall nur eine falsche Farbe heraus, ansonsten etwas gröberer Unfug. Um diese Fehlerquelle zu umgehen, bringt Python zwei passende Bibliotheken mit: Colorama [9] und Termcolor [10]. Beide stehen über den Python Package Index zur ergänzenden Installation bereit. Colorama erscheint uns eingängiger, daher konzentrieren wir uns hier darauf und lassen Termcolor außen vor.
Listing 4 implementiert dasselbe Verhalten wie die Listings 2 und**3, allerdings unter Rückgriff auf die Colorama-Bibliothek. Geändert hat sich nur wenig: Zeile 1 importiert die beiden Klassen Fore (Vordergrund) und Style (Texteigenschaften) aus der Colorama-Bibliothek, die Zeilen 4 bis 13 legen die Farbcodes lesefreundlich unter Rückgriff auf die in Fore definierten Konstanten fest. Die Ausgabe des Programms ist identisch zu der von Listing 3 (Abbildung 4).
Listing 4
Colorama
from colorama import Fore, Style
# Farben festlegen
basicColorSet = {
"schwarz": Fore.BLACK,
"rot": Fore.RED,
"grün": Fore.GREEN,
"gelb": Fore.YELLOW,
"blau": Fore.BLUE,
"pink": Fore.MAGENTA,
"hellblau": Fore.CYAN,
"weiss": Fore.WHITE
}
# Reset-Code festlegen
resetCode = Style.RESET_ALL
# Text in der entsprechenden Farbe ausgeben
for item in basicColorSet:
print ("%s %s" % (basicColorSet[item],item))
# Farbeinstellungen zurücksetzen
print (resetCode)
Für Hintergrundfarben kennt Colorama die Klasse Back mit ähnlich vordefinierten Farbwerten. Sie lässt sich exakt so nutzen wie die Klasse Fore. Zu Hervorhebungen und zur Dekoration von Text kommen wir im Folgenden noch.
Zuvor sei aber ein praktisches Hilfsmittel genannt, Colortest-python aus dem gleichnamigen Debian-Paket [11], das das Terminal mit einem Farbspektrum füllt. Abbildung 5 stellt die Ausgabe in einem Gnome-Terminal dar.
Farbkombinationen
Ärgerlicherweise lässt sich nicht ohne viel Aufwand herausfinden, welche Hintergrundfarbe das Terminal verwendet, in dem unser Bash-Kommando oder Python-Skript gerade läuft. Bibliotheken wie Term-background [12] lesen dazu die Umgebungsvariablen aus und stützen sich dabei auf Escape-Sequenzen, die allerdings nicht jede Terminalemulation versteht [13].
Wenn wir aber schon an der Farbkombination herumpfuschen, müssen wir wenigstens dafür sorgen, dass die Ausgabe lesbar bleibt. Die Benutzung von Farben und deren Akzeptanz durch einen Benutzer ist ja sehr subjektiv und hat stets auch einen kulturellen Bezug. Es kommt also darauf an, wie der Anwender die gewählte Farbe interpretiert und welche Aktion er daraus ableitet. Hinzu kommen Sehschwächen wie Farbenblindheit, die eine Interpretation über die Farbe erschweren oder sogar unmöglich machen.
Die Bedeutung einer gewählten Farbe ist kulturell geprägt. Im mitteleuropäischen Kulturkreis verbindet man Rot mit einem Fehler, Gelb mit einer Warnung und Grün mit einem Erfolg (siehe dazu die Visual Design Principles [14]). Andere Kulturkreise haben einen anderen Bezug zu Farben.
Bei der Auswahl einer Farbkombination gilt es grundsätzlich, auf den Kontrast zu achten. Die Kombination [15] aus Vorder- und Hintergrundfarbe [16] muss zusammenpassen und einen möglichst hohen Kontrast liefern. Je höher der Kontrast, umso größer ist die Lesbarkeit der Ausgabe auch bei schlechten Lichtverhältnissen.
Zu einem hellen Hintergrund passt eine möglichst dunkle Textfarbe wie Schwarz oder Dunkelblau und umgekehrt. Ein dunkler Hintergrund “verschluckt” tendenziell hell gefärbten Text, der sich daher mit einer Hervorhebung wie Fettschrift leichter lesen lässt.
Um den Text passend zu dekorieren, bieten sich etwa die Beispiele aus der Tabelle “Text dekorieren (Auswahl)” an. Sie stellt die ANSI-Escape-Sequenz [17] für die Bash und den vordefinierten Wert in der Colorama-Bibliothek für Python [18] gegenüber. Der Programmcode in Listing 5 demonstriert eine Textausgabe in weißer Schrift auf blauem Hintergrund, sowohl in normaler als auch in gefetteter Ausgabe. Letztere kann man deutlich besser lesen (Abbildung 6).
|
Beschreibung |
ANSI-Escape-Sequenz |
… für Python |
Konstante in Colorama |
|---|---|---|---|
|
Fettung |
|
|
|
|
Invertierung |
|
|
nicht vorhanden |
|
Dimmen |
|
|
|
Listing 5
Dekorierter Text
from colorama import Fore, Back, Style
# Vordergrund und Hintergrund festlegen
foreground = Fore.WHITE
background = Back.BLUE
# Fettdruck festlegen
bold = Style.BRIGHT
# Reset-Flag festlegen
resetCode = Style.RESET_ALL
# Text definieren
textNormal = " weiss auf blau "
textBold = " weiss auf blau (fett) "
# Text ausgeben
print ("%s%s%s" % (background, foreground, textNormal))
print ("%s%s%s%s" % (background, bold, foreground, textBold))
# Farbwerte zurücksetzen
print (resetCode)

Abbildung 6: Der dekorierte Text aus Listing 5.
Wozu das Ganze?
Abschließend kehren wir noch einmal zu der grundlegenden Frage zurück, ob Farbe in der Ausgabe überhaupt sinnvoll ist – schließlich unterstützen einige Terminals nur eine begrenzte Menge von Farben. Ein Xterm kennt lediglich acht Grundfarben, erst dessen Nachfolger unterstützen mehr Varianten.
Des Weiteren ergibt eine farbige Ausgabe keinen Sinn, wenn ein Python-Skript Teil einer Pipe ist oder seine Ausgabe umgeleitet wird (Redirection). Beide Faktoren lassen sich jedoch mit wenigen Zeilen Python-Code klären.
Zunächst bestimmen wir mithilfe des Python-Moduls os den Terminaltyp über die Umgebungsvariable [19] TERM [20]. Danach benutzen wir die Methode isatty() [21] aus dem sys-Modul, um festzustellen, ob das Skript in einem Terminal aufgerufen wurde. Listing 6 fasst beide Tests zusammen.
Listing 6
Aufruftest
# Libraries os und sys laden
import os, sys
# Vorgabewert False
colouredOutput = False
# In einem Terminal?
if sys.stdout.isatty():
# Ein Xterm mit 256 Farben?
if os.environ["TERM"] == 'xterm-256color':
# ja -> Farbausgabe verwenden
colouredOutput = True
else:
# kein Terminal
[...]
Fazit
Schon in der Bash lässt sich mit nur wenig Aufwand die Terminalausgabe eigener Programme mit Farbtupfern versehen, die Python-Bibliothek Colorama vereinfacht die Angelegenheit noch weiter. Das ist aber noch keineswegs das Ende der Fahnenstange: Es gibt kleine Werkzeuge, die sich bei bestehender Software einklinken können, um auch deren Ausgabe mit Farbe aufzupeppen. Diesen Tools widmen wir in einem Folgebeitrag unsere volle Aufmerksamkeit. (jlu)
Danksagung
Der Autor bedankt sich bei Benjamin Schieder und Axel Beckert für deren Kritik und Unterstützung beim Erstellen dieses Artikels.
Über den Autor
Frank Hofmann arbeitet zumeist von unterwegs aus, bevorzugt in Berlin, Genf und Kapstadt, als Entwickler, Trainer und Autor. Er gehört zu den Verfassern des Debian-Paketmanagement-Buchs (https://dpmb.org).
Infos
-
Debian-Paket Ncurses-bin: https://packages.debian.org/bookworm/ncurses-bin
-
Zu Befehl – Farbe auf der Shell: Heike Jurzik, “Ein neuer Anstrich”, LU 08/2007, S. 86, https://www.linux-community.de/13184
-
“Adding colors to Bash scripts”: https://dev.to/ifenna__/adding-colors-to-bash-scripts-48g4
-
Farben im Bash Prompt Howto: https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
-
Debian-Paket Colortest: https://packages.debian.org/bookworm/colortest
-
“Build your own Command Line with ANSI escape codes”: http://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html
-
Python-Training: https://github.com/hofmannedv/training-python/tree/master/ansicolor
-
Colorama: https://pypi.org/project/colorama/
-
Termcolor: https://pypi.org/project/termcolor/
-
Debian-Paket Colortest-python: https://packages.debian.org/bookworm/colortest-python
-
Term-background: https://pypi.org/project/term-background/
-
“Xterm color queries”: https://www.talisman.org/~erlkonig/documents/xterm-color-queries/
-
“Visual Design Principles”: https://github.com/hofmannedv/visual-design-principles
-
“26 best color combinations for your next design”: https://webflow.com/blog/best-color-combinations
-
“Color Combinations Guide: The Ultimate Cheat Sheet”: https://www.oberlo.com/blog/color-combinations-cheat-sheet
-
“ANSI Escape Sequences”: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
-
“Print Colors in Python terminal”: https://www.geeksforgeeks.org/print-colors-python-terminal/
-
“Python Env Vars – How to Get an Environment Variable in Python”: https://www.freecodecamp.org/news/python-env-vars-how-to-get-an-environment-variable-in-python/
-
“The
$TERMEnvironment Variable”: https://www.baeldung.com/linux/term-environment-variable -
isatty(): https://docs.python.org/3/library/io.html#io.IOBase.isatty









