Gibt es eine Umgebungsvariable?
Ja. Es ist die TERM
Umgebungsvariable. Dies liegt daran, dass im Rahmen des Entscheidungsprozesses mehrere Dinge verwendet werden.
Eine Verallgemeinerung ist hier schwierig, da sich nicht alle Programme auf ein einziges Entscheidungsflussdiagramm einigen. In der Tat ist GNU grep
, wie in M. Kitts Antwort erwähnt, ein gutes Beispiel für einen Ausreißer, der einen etwas ungewöhnlichen Entscheidungsprozess mit unerwarteten Ergebnissen anwendet. Ganz allgemein gesagt:
- Die Standardausgabe muss ein Endgerät sein, wie von festgelegt
isatty()
.
- Das Programm muss in der Lage sein, den Datensatz für den Terminaltyp in der termcap / terminfo-Datenbank nachzuschlagen.
- Es muss also einen Terminaltyp geben, nach dem gesucht werden kann. Die
TERM
Umgebungsvariable muss vorhanden sein und ihr Wert muss mit einem Datenbankdatensatz übereinstimmen.
- Es muss daher eine terminfo / termcap-Datenbank vorhanden sein. Bei einigen Implementierungen des Subsystems kann der Speicherort der Termcap-Datenbank mithilfe einer
TERMCAP
Umgebungsvariablen angegeben werden. Daher gibt es bei einigen Implementierungen eine zweite Umgebungsvariable.
- Der Datensatz termcap / terminfo muss angeben, dass der Terminaltyp Farben unterstützt. Es gibt ein
max_colors
Feld in terminfo. Es ist nicht für Terminaltypen festgelegt, die nicht über Farbfunktionen verfügen. In der Tat gibt es eine Terminfo-Konvention, die besagt, dass für jeden farbbaren Terminaltyp ein weiterer Datensatz mit -m
oder -mono
an den Namen angehängt wird, der keine Farbfähigkeit angibt.
- Der Datensatz termcap / terminfo muss dem Programm die Möglichkeit geben, die Farben zu ändern. Es gibt
set_a_foreground
und set_a_background
Felder in terminfo.
Es ist ein bisschen komplexer als nur zu überprüfen isatty()
. Es wird durch verschiedene Dinge noch komplizierter:
- Einige Anwendungen fügen Befehlszeilenoptionen oder Konfigurationsflags hinzu, die die
isatty()
Prüfung außer Kraft setzen , sodass das Programm immer oder nie davon ausgeht, dass es ein (färbbares) Terminal als Ausgabe hat. Zum Beispiel:
- GNU
ls
hat die --color
Befehlszeilenoption.
- BSD
ls
untersucht die Umgebungsvariablen CLICOLOR
(Abwesenheit bedeutet nie ) und CLICOLOR_FORCE
(Anwesenheit bedeutet immer ) und bietet auch die -G
Befehlszeilenoption an.
- Einige Anwendungen verwenden termcap / terminfo nicht und haben fest verdrahtete Antworten auf den Wert von
TERM
.
- Nicht alle Terminals verwenden ECMA-48- oder ISO 8613-6-SGR-Sequenzen, die leicht mit dem falschen Namen "ANSI-Escape-Sequenzen" versehen sind, um die Farben zu ändern. Der Termcap / Terminfo-Mechanismus wurde entwickelt, um Anwendungen von der direkten Kenntnis der genauen Steuersequenzen zu isolieren. (Darüber hinaus gibt es ein Argument dafür, dass niemand SGR-Sequenzen nach ISO 8613-6 verwendet, da sich alle über den Fehler einig sind, Semikolon als Trennzeichen für RGB-Farb-SGR-Sequenzen zu verwenden. Die Norm gibt tatsächlich Doppelpunkte an.)
Wie bereits erwähnt, grep
weist GNU tatsächlich einige dieser zusätzlichen Komplexitäten auf. Es konsultiert nicht termcap / terminfo, verkabelt die auszugebenden Steuersequenzen und verkabelt eine Antwort auf die TERM
Umgebungsvariable.
Der Linux / Unix-Port hat diesen Code , der die Einfärbung nur ermöglicht, wenn die TERM
Umgebungsvariable existiert und ihr Wert nicht mit dem festverdrahteten Namen übereinstimmt dumb
:
int
should_colorize (nichtig)
{
char const * t = getenv ("TERM");
return t && strcmp (t, "dumm")! = 0;
}
Selbst wenn dies der Fall TERM
ist xterm-mono
, wird GNU grep
beschließen, Farben auszugeben, obwohl andere Programme dies vim
nicht tun.
Der Win32-Port hat diesen Code , der die Einfärbung entweder dann aktiviert, wenn die TERM
Umgebungsvariable nicht vorhanden ist oder wenn sie vorhanden ist und ihr Wert nicht mit dem festverdrahteten Namen übereinstimmt dumb
:
int
should_colorize (nichtig)
{
char const * t = getenv ("TERM");
Rückkehr ! (t && strcmp (t, "dumm") == 0);
}
GNU grep
Probleme mit Farbe
grep
Die Färbung von GNU ist eigentlich berüchtigt. Da die Terminal-Ausgabe nicht ordnungsgemäß erstellt wird, sondern nur einige festverdrahtete Steuersequenzen an verschiedenen Stellen der Ausgabe ausgeführt werden, in der vergeblichen Hoffnung, dass dies ausreichend ist, wird unter bestimmten Umständen tatsächlich eine falsche Ausgabe angezeigt.
Unter diesen Umständen muss etwas am rechten Rand des Terminals eingefärbt werden. Programme, die Terminalausgaben korrekt ausführen, müssen automatische rechte Ränder berücksichtigen. Zusätzlich zu der geringen Möglichkeit, dass das Terminal möglicherweise nicht über sie verfügt (dh das auto_right_margin
Feld in terminfo), folgt das Verhalten von Terminals, die über automatische rechte Ränder verfügen, häufig dem DEC VT-Präzedenzfall des Zeilenumbruchs . GNU grep
berücksichtigt dies nicht und erwartet naiv einen sofortigen Zeilenumbruch , und seine farbige Ausgabe geht schief.
Farbausgabe ist keine einfache Sache.
Weitere Lektüre