20

I am trying to save the output of a command to a file. The command is:

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

However the resulting output.txt file when opened (by gedit and jedit on ubuntu) gives me this:

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

When it should really look like this:

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

I thought it might be a problem of encoding, I checked the encoding of the file, file -bi output.txt which outputs text/plain; charset=us-ascii.

I thought maybe if I change the encoding to utf-8 the problem would be fixed so I tried this:

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

but it didn't make a difference.

What can I do to solve this problem?

The problem isn't that I'm trying to view the syntax-highlighted version (I didn't have a problem viewing it in the first place). I need to save the AST generated by clang to a file and then parse it, which would be difficult with the colour information left in.

54

It has nothing to do with codepages/encoding. Your output isn't plain text. It contains the sequences like [0;1;32m. These strings (there is a, not shown, [escape] character as well before each of these) are instructions to the terminal to show text bold, italics, in various colors, etc. This results in easier to read output, if your terminal supports it.

There should be an option to tell clang not to try to beautify the output, but use plain text instead. Check the manual. (I don't have one handy, so I can't tell you what the proper command would be.)

  • 15
    Thanks, that was the cause. I tried clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txt which gave me the correct output. – maou Apr 28 '16 at 12:51
  • 9
    An alternative fix, if Clang is reasonably well-behaved (which it obviously isn't, if it's sending terminal codes without checking isatty(stdout)) is to set TERM to (e.g.) dumb. – Toby Speight Apr 28 '16 at 15:18
  • 4
    Re "This results in easier to read output, if your terminal supports it.", that is, of course, an opinion. Doesn't always work that way, as for instance when the colorizing app outputs dark blue text on your black background :-( – jamesqf Apr 28 '16 at 17:18
  • 4
    Any reasonable piece of software should detect that its output is being redirected to file and turn off colorization in that case. – n0rd Apr 29 '16 at 17:40
  • 1
    @n0rd Ideally yes, but I've seen enough situations where isattty() wasn't given false on redirected output. And in some cases a user might want the escape codes redirected (e.g. to view later or pipe to netcat to view on another system, just to give 2 use-cases). So try to guess, but also allow the user to turn it on/off overriding the guess in case it was wrong. That would be the best solution. – Tonny Apr 29 '16 at 22:42
12

Alternatively, instead of removing the colours from the output, you can view the coloured output in your terminal by using the raw option of less

less -r output.txt
2

Those characters, such as [0;33m look like terminal output control to me. They're part of a set of escape sequences that is frequently used for applying colors to text in the terminal. In its raw state like this it is also often used for applying color to the bash prompt itself - Here's what I've been using in .bashrc for years on all of my machines:

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

(Most think it's ugly, but I like it).

See if you are able to find a switch to remove any color coding or the like from the output of your commands and see if that helps.

  • 13
    [...] "look like bash's output control to me" They have nothing to do with bash. It is the terminal what they are for. – glglgl Apr 28 '16 at 14:51
  • 1
    As @glglgl said, they're not Bash-specific, they're a xterm-related thing. See this excellent answer by the lead developer of xterm. – cat Apr 28 '16 at 23:43
  • @glglgl Alright, answer edited accordingly. I first saw it when migrating from fBSD to linux a few years back, which was also when I started using bash, so I thought it was a product of the latter. – Jarmund Apr 29 '16 at 6:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.