Gibt es eine Umgebungsvariable?
Ja. Es ist die TERMUmgebungsvariable. 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
TERMUmgebungsvariable 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
TERMCAPUmgebungsvariablen 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_colorsFeld 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 -moder -monoan 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_foregroundund set_a_backgroundFelder 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
lshat die --colorBefehlszeilenoption.
- BSD
lsuntersucht die Umgebungsvariablen CLICOLOR(Abwesenheit bedeutet nie ) und CLICOLOR_FORCE(Anwesenheit bedeutet immer ) und bietet auch die -GBefehlszeilenoption 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, grepweist 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 TERMUmgebungsvariable.
Der Linux / Unix-Port hat diesen Code , der die Einfärbung nur ermöglicht, wenn die TERMUmgebungsvariable 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 TERMist xterm-mono, wird GNU grepbeschließen, Farben auszugeben, obwohl andere Programme dies vimnicht tun.
Der Win32-Port hat diesen Code , der die Einfärbung entweder dann aktiviert, wenn die TERMUmgebungsvariable 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 grepProbleme mit Farbe
grepDie 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_marginFeld 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 grepberücksichtigt dies nicht und erwartet naiv einen sofortigen Zeilenumbruch , und seine farbige Ausgabe geht schief.
Farbausgabe ist keine einfache Sache.
Weitere Lektüre