Warum erzeugt clang bei der Weiterleitung unverständlichen Text?

3840
maou

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 gibt mir jedoch Folgendes (von gedit und jedit auf Ubuntu):

[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 Problem der Kodierung sein, ich habe die Kodierung der Datei überprüft, file -bi output.txtdie sie ausgibt text/plain; charset=us-ascii.

Ich dachte vielleicht, wenn ich die Kodierung in utf-8 ändere, wäre das Problem behoben, also 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 Syntax hervorgehobene Version anzuzeigen (ich hatte überhaupt kein Problem damit, sie zu sehen). Ich muss den von clang erzeugten AST in einer Datei speichern und dann analysieren, was mit den verbleibenden Farbinformationen schwierig wäre.

20
Es ist erwähnenswert, dass `>` keine Ausgabe generiert, sondern lediglich der Shell bezeichnet, dass Sie die Ausgabe Ihres `clang`-Befehls in die angegebene Datei und nicht in das Terminal einfügen möchten. Danach betrachten Sie es so, dass Farbcodes nicht auf dieselbe Weise zulässig sind. Wenn Sie die Datei "cat" machen würden, würde sie funktionieren, da das Terminal die Kontrolle übernehmen würde, und Sie können "less" mit dem "-R" -Flag genauso machen. Sammitch vor 8 Jahren 4
Mögliches Duplikat von [Wie kann ich Vim anweisen, ANSI-Escape-Codes ordnungsgemäß anzuzeigen?] (Http://superuser.com/questions/358409/how-can-i-tell-vim-to-show-ansi-escape-codes- richtig) Scott vor 8 Jahren 1
Siehe auch [ANSI-Escape-Code vor dem Verarbeiten verarbeiten] (/ q / 489151/150988), Befehl [`column` verwirrt durch ANSI-Farbumbrüche] (/ q / 648665/150988), [ANSI-Escape-Sequenzen in Terminalausgabe verhindern] (/ q / 170532/150988) und [Warum kann "cat / dev / urandom" Ihr Terminal beschädigen?] (/ q / 637860/150988 # 637867) Scott vor 8 Jahren 0
@Scott - Ich versuche nicht, die Ausgabe anzuzeigen, ich versuche, sie in einer Datei zu speichern, ohne die Farbinformationen zu belassen, was das Analysieren der Datei unnötig kompliziert machen würde. maou vor 8 Jahren 0

3 Antworten auf die Frage

54
Tonny

Es hat nichts mit Codepages / Encoding zu tun. Ihre Ausgabe ist kein Klartext. Es enthält die Sequenzen wie [0;1;32m. Diese Zeichenfolgen (es gibt ein nicht dargestelltes [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 leicht lesbaren Ausgabe des Terminals unterstützt es.

Es sollte eine Option geben, mit der clang angesprochen werden soll, die Ausgabe nicht zu verschönern, sondern stattdessen Klartext zu verwenden. Überprüfen Sie das Handbuch. (Ich habe kein Handy zur Hand, daher kann ich Ihnen nicht sagen, was der richtige Befehl wäre.)

Danke, das war die Ursache. Ich habe 'clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp> output.txt' ausprobiert, was mir die korrekte Ausgabe ergab. maou vor 8 Jahren 15
Ein alternativer Fix, wenn Clang einigermaßen brav ist (was offensichtlich nicht der Fall ist, wenn Terminalcodes gesendet werden, ohne `isatty (stdout)` zu überprüfen), soll TERM auf (zB) dumm gesetzt werden. Toby Speight vor 8 Jahren 9
Betreff: "Dies führt zu einer besser lesbaren Ausgabe, wenn Ihr Terminal dies unterstützt.", Das ist natürlich eine Meinung. Funktioniert nicht immer so, zum Beispiel wenn die colorisierende App dunkelblauen Text auf Ihrem schwarzen Hintergrund ausgibt :-( jamesqf vor 8 Jahren 4
@jamesqf Du hast einen Punkt. Dunkelgrün auf Rot (der Hintergrund wurde auch von der App auf Rot gesetzt!) Ist ein weiterer Augenschmerz, dem ich begegnet bin. Wie hat jemals jemand gedacht, dass das eine gute Idee war .. Tonny vor 8 Jahren 0
Jede sinnvolle Software sollte erkennen, dass ihre Ausgabe in eine Datei umgeleitet wird, und in diesem Fall die Färbung deaktivieren. n0rd vor 8 Jahren 4
@ n0rd Idealerweise ja, aber ich habe genug Situationen gesehen, in denen isattty () bei der umgeleiteten Ausgabe nicht falsch angegeben wurde. In einigen Fällen möchte der Benutzer möglicherweise, dass die Escape-Codes umgeleitet werden (z. B. um die Ansicht später zu ändern oder an netcat weiterzuleiten, um sie auf einem anderen System anzuzeigen, um nur zwei Anwendungsfälle anzugeben). Versuchen Sie also zu erraten, aber erlauben Sie dem Benutzer auch, ihn ein- oder auszuschalten und die Vermutung außer Kraft zu setzen, falls er falsch war. Das wäre die beste Lösung. Tonny vor 8 Jahren 1
@ n0rd: Ja, aber leider gibt es eine Menge unvernünftiger Software. Nicht nur eine farbige Ausgabe für Webbrowser: Beachten Sie die Schwierigkeiten, die beispielsweise auftreten, wenn MathJax auf schwarzem Hintergrund angezeigt wird :-( jamesqf vor 8 Jahren 0
Und dann gibt es die Idioten, die mit `isatty (stdin)` feststellen, ob sie Farbcodes ausgeben können. Michael Hampton vor 8 Jahren 0
12
987poiuytrewq

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

less -r output.txt 
2
Jarmund

Diese Zeichen, wie [0;33mdie Terminalausgabe, sehen für mich aus. Sie sind Teil eines Satzes von Escape-Sequenzen, die häufig zum Anwenden von Farben auf Text im Terminal verwendet werden. Im Rohzustand wie diesem wird er auch häufig zum Auftragen von Farbe auf die Bash-Eingabeaufforderung selbst verwendet. Hier ist, was ich seit .bashrcJahren auf all meinen Maschinen verwende:

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 Befehlsausgabe einen Schalter zum Entfernen von Farbkodierungen oder Ähnlichem finden können und ob dies hilfreich ist.

[...] "Sieht aus wie die Ausgabesteuerung von bash" Sie haben nichts mit bash zu tun. Es ist das Terminal, wofür sie sind. glglgl vor 8 Jahren 13
Wie @glglgl gesagt hat, sie sind nicht Bash-spezifisch, sie sind eine 'xterm'-Sache. Siehe [diese ausgezeichnete Antwort] (http://unix.stackexchange.com/questions/264937/whats-the-maximum-length-for-a-multibyte-escape-sequence) durch den Hauptentwickler von `xterm`. cat vor 8 Jahren 1
@glglgl Okay, die Antwort wurde entsprechend bearbeitet. Ich habe es zum ersten Mal gesehen, als ich vor ein paar Jahren von fBSD zu Linux gewandert war. Zu diesem Zeitpunkt begann auch ich mit bash, also dachte ich, es sei ein Produkt des letzteren. Jarmund vor 8 Jahren 0