Warum erzeugt Clang unverständlichen Text, wenn er umgeleitet wird?

20

Ich versuche, die Ausgabe eines Befehls in einer Datei zu speichern. Der Befehl lautet:

clang -Xclang -ast-dump -fsyntax-only main.cpp > output.txt

Die resultierende output.txt-Datei beim Öffnen (von gedit und jedit auf Ubuntu) gibt mir jedoch Folgendes:

[0;1;32mTranslationUnitDecl[0m[0;33m 0x4192020[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x4192558[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __int128_t[0m [0;32m'__int128'[0m
[0;34m| `-[0m[0;32mBuiltinType[0m[0;33m 0x4192270[0m [0;32m'__int128'[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x41925b8[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __uint128_t[0m [0;32m'unsigned __int128'[0m
[0;34m| `-[0m[0;32mBuiltinType[0m[0;33m 0x4192290[0m [0;32m'unsigned __int128'[0m
...

Wann sollte es wirklich so aussehen:

TranslationUnitDecl 0x4e46020 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x4e46558 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x4e46270 '__int128'
|-TypedefDecl 0x4e465b8 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x4e46290 'unsigned __int128'
...

Ich dachte, es könnte ein Codierungsproblem sein. Ich habe die Codierung der Datei überprüft, file -bi output.txtdie ausgegeben wird text/plain; charset=us-ascii.

Ich dachte, wenn ich die Codierung auf utf-8 ändere, ist das Problem möglicherweise behoben. Deshalb habe ich Folgendes versucht:

clang -Xclang -ast-dump -fsyntax-only main.cpp | iconv -f us-ascii -t UTF-8 > output.txt

aber es machte keinen Unterschied.

Was kann ich tun, um dieses Problem zu lösen?

Das Problem ist nicht, dass ich versuche, die Version mit der hervorgehobenen Syntax anzuzeigen (ich hatte überhaupt keine Probleme, sie anzuzeigen). Ich muss den durch Klirren erzeugten AST in einer Datei speichern und dann analysieren, was mit den verbleibenden Farbinformationen schwierig wäre.

maou
quelle
4
Es ist zu beachten, dass >keine Ausgabe generiert wird, sondern lediglich die Shell bezeichnet, die die Ausgabe Ihres clangBefehls in die angegebene Datei und nicht in das Terminal schreiben soll. Danach betrachten Sie es auf eine Weise, die Farbcodes nicht auf die gleiche Weise zulässt. Wenn Sie in catder Datei wären, würde es funktionieren, als würde das Terminal übernehmen, und Sie können lessdas gleiche mit der -RFlagge machen.
Sammitch
@Scott - Ich versuche nicht, die Ausgabe anzuzeigen, sondern sie in einer Datei zu speichern, ohne die Farbinformationen zu belassen, was das Parsen der Datei unnötig kompliziert machen würde.
Maou

Antworten:

54

Es hat nichts mit Codepages / Codierung zu tun. Ihre Ausgabe ist kein reiner Text. Es enthält die Sequenzen wie [0;1;32m. Diese Zeichenfolgen (es gibt auch ein nicht gezeigtes [Escape] -Zeichen vor jedem dieser Zeichen) sind Anweisungen an das Terminal, um Text fett, kursiv, in verschiedenen Farben usw. anzuzeigen. Dies führt zu einer einfacheren Ausgabe, wenn Ihr Terminal unterstützt es.

Es sollte eine Option geben, mit der clang angewiesen wird, nicht zu versuchen, die Ausgabe zu verschönern, sondern stattdessen einfachen Text zu verwenden. Überprüfen Sie das Handbuch. (Ich habe keine zur Hand, daher kann ich Ihnen nicht sagen, was der richtige Befehl wäre.)

Tonny
quelle
15
Danke, das war die Ursache. Ich habe versucht, clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txtdie mir die richtige Ausgabe gab.
Maou
9
Eine alternative Korrektur, wenn sich Clang einigermaßen gut benimmt (was offensichtlich nicht der Fall ist, wenn Terminalcodes ohne Überprüfung gesendet werden isatty(stdout)), ist die Einstellung TERMauf (z dumb. B.) .
Toby Speight
4
Zu "Dies führt zu einer einfacheren Lesbarkeit der Ausgabe, wenn Ihr Terminal dies unterstützt.", Das ist natürlich eine Meinung. Funktioniert nicht immer so, zum Beispiel, wenn die Kolorierungs-App dunkelblauen Text auf Ihrem schwarzen Hintergrund ausgibt :-(
jamesqf
4
Jede vernünftige Software sollte erkennen, dass ihre Ausgabe in eine Datei umgeleitet wird, und in diesem Fall die Einfärbung deaktivieren.
29.
1
@ n0rd Idealerweise ja, aber ich habe genug Situationen gesehen, in denen isattty () bei umgeleiteten Ausgaben nicht falsch angegeben wurde. In einigen Fällen möchte ein Benutzer möglicherweise, dass die Escape-Codes umgeleitet werden (z. B. um sie später anzuzeigen oder um sie an netcat weiterzuleiten, um sie auf einem anderen System anzuzeigen, nur um 2 Anwendungsfälle anzugeben). Versuchen Sie also zu raten, lassen Sie aber auch zu, dass der Benutzer das Raten ein- und ausschaltet, falls es falsch war. Das wäre die beste Lösung.
Tonny
12

Anstatt die Farben aus der Ausgabe zu entfernen, können Sie alternativ die farbige Ausgabe in Ihrem Terminal anzeigen, indem Sie die Option raw von verwenden less

less -r output.txt
987poiuytrewq
quelle
2

Diese Zeichen [0;33msehen für mich wie eine Terminal-Ausgabesteuerung aus. Sie sind Teil einer Reihe von Escape-Sequenzen, die häufig zum Anwenden von Farben auf Text im Terminal verwendet werden. In diesem Rohzustand wird es auch häufig zum Auftragen von Farbe auf die Bash-Eingabeaufforderung selbst .bashrcverwendet.

export PS1='\[\033[1;33m\]\u\[\033[1;35m\]@\[\033[1;32m\]\h\[\033[0;36m\]\w\[\033[1;37m\]\$ \[\033[0;37m\]'

(Die meisten finden es hässlich, aber ich mag es).

Prüfen Sie, ob Sie in der Lage sind, einen Schalter zum Entfernen von Farbcodierungen oder Ähnlichem aus der Ausgabe Ihrer Befehle zu finden, und prüfen Sie, ob dies hilfreich ist.

Jarmund
quelle
13
[...] "Sieh für mich wie die Ausgabesteuerung von Bash aus" Sie haben nichts mit Bash zu tun. Es ist das Terminal, wofür sie sind.
Glglgl
1
Wie @glglgl sagte, sind sie nicht Bash-spezifisch, sie sind eine xtermverwandte Sache. Sehen Sie sich diese hervorragende Antwort des leitenden Entwicklers von an xterm.
Katze
@glglgl Alles klar, Antwort entsprechend bearbeitet. Ich habe es zum ersten Mal gesehen, als ich vor ein paar Jahren von fBSD auf Linux umgestiegen bin. Damals habe ich auch angefangen, bash zu verwenden.
Jarmund