Perché clang genera testo incomprensibile quando viene reindirizzato?


20

Sto cercando di salvare l'output di un comando in un file. Il comando è:

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

Tuttavia il file output.txt risultante quando aperto (da gedit e jedit su Ubuntu) mi dà questo:

[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
...

Quando dovrebbe davvero apparire così:

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'
...

Ho pensato che potesse essere un problema di codifica, ho controllato la codifica del file, file -bi output.txtche genera text/plain; charset=us-ascii.

Ho pensato che se avessi cambiato la codifica in utf-8 il problema sarebbe stato risolto, quindi ho provato questo:

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

ma non ha fatto differenza.

Cosa posso fare per risolvere questo problema?

Il problema non è che sto provando a visualizzare la versione evidenziata dalla sintassi (in primo luogo non ho avuto problemi a visualizzarla). Devo salvare l'AST generato da clang in un file e quindi analizzarlo, il che sarebbe difficile con le informazioni sul colore rimaste.


4
Vale la pena notare che >non genera output, indica semplicemente alla shell che si desidera inserire l'output del clangcomando nel file specificato, anziché il terminale. Dopo di che lo stai visualizzando in un modo che non consente i codici colore allo stesso modo. Se tu fossi catsul file, funzionerebbe come il terminale prenderebbe il controllo e puoi lessfare lo stesso con la -Rbandiera.
Sammitch,



@Scott - Non sto provando a visualizzare l'output, sto cercando di salvarlo in un file senza lasciare le informazioni sul colore, il che renderebbe inutilmente complicato l'analisi del file.
Maou,

Risposte:


54

Non ha nulla a che fare con codepages / codifica. Il tuo output non è un testo semplice. Contiene le sequenze simili [0;1;32m. Queste stringhe (c'è anche un carattere [escape], non mostrato, prima di ognuna di queste) sono istruzioni per il terminale per mostrare il testo in grassetto, corsivo, in vari colori, ecc. Ciò risulta più facile da leggere in output, se il tuo terminale lo supporta.

Dovrebbe esserci un'opzione per dire a clang di non tentare di abbellire l'output, ma utilizzare invece il testo semplice. Controlla il manuale. (Non ne ho uno a portata di mano, quindi non posso dirti quale sarebbe il comando corretto.)


15
Grazie, questa era la causa. Ho provato clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txtche mi ha dato l'output corretto.
Maou,

9
Una soluzione alternativa, se Clang è ragionevolmente ben educato (cosa che ovviamente non lo è, se sta inviando codici di terminale senza controllo isatty(stdout)) è di impostare TERM(ad esempio) dumb.
Toby Speight,

4
Ri "Questo risulta più facile da leggere in uscita, se il tuo terminale lo supporta.", Che è, ovviamente, un'opinione. Non funziona sempre in questo modo, come ad esempio quando l'app colorante produce testo blu scuro sullo sfondo nero :-(
jamesqf,

4
Qualsiasi software ragionevole dovrebbe rilevare che il suo output viene reindirizzato su file e disattivare la colorazione in quel caso.
n.

1
@ n0rd Idealmente sì, ma ho visto abbastanza situazioni in cui isattty () non è stato dato falso sull'output reindirizzato. E in alcuni casi un utente potrebbe desiderare che i codici di escape vengano reindirizzati (ad esempio per visualizzare in seguito o reindirizzare a netcat per visualizzare su un altro sistema, solo per fornire 2 casi d'uso). Quindi prova a indovinare, ma consenti anche all'utente di attivarlo / disattivarlo ignorando l'ipotesi in caso di errore. Questa sarebbe la soluzione migliore.
Tonny,

12

In alternativa, invece di rimuovere i colori dall'output, è possibile visualizzare l'output colorato nel terminale utilizzando l'opzione raw di less

less -r output.txt

2

Quei personaggi, come ad esempio, mi [0;33msembrano il controllo dell'uscita terminale. Fanno parte di una serie di sequenze di escape che vengono spesso utilizzate per applicare i colori al testo nel terminale. Allo stato grezzo come questo viene spesso utilizzato anche per applicare il colore al prompt di bash stesso. Ecco quello che utilizzo .bashrcda anni su tutte le mie macchine:

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

(La maggior parte pensa che sia brutto, ma mi piace).

Vedi se riesci a trovare un interruttore per rimuovere qualsiasi codice colore o simili dall'output dei tuoi comandi e vedi se questo aiuta.


13
[...] "mi sembra il controllo dell'output di bash" Non hanno nulla a che fare con bash. È il terminale a cui servono.
glglgl,

1
Come ha detto @glglgl, non sono specifici di Bash, sono una xtermcosa correlata. Guarda questa eccellente risposta dello sviluppatore principale di xterm.
gatto,

@glglgl Va bene, risposta modificata di conseguenza. L'ho visto per la prima volta durante la migrazione da fBSD a Linux qualche anno fa, che era anche quando ho iniziato a usare bash, quindi ho pensato che fosse un prodotto di quest'ultimo.
Jarmund,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.