Почему clang генерирует неразборчивый текст при перенаправлении?

20

Я пытаюсь сохранить вывод команды в файл. Команда:

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

Однако полученный файл output.txt при открытии (с помощью gedit и jedit в 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
...

Когда это действительно должно выглядеть так:

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

Я думал, что это может быть проблема кодирования, я проверил кодировку файла, file -bi output.txtкоторый выводит text/plain; charset=us-ascii.

Я подумал, может быть, если я изменю кодировку на utf-8, проблема будет исправлена, поэтому я попробовал это:

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

но это не имело значения.

Что я могу сделать, чтобы решить эту проблему?

Проблема не в том, что я пытаюсь просмотреть выделенную синтаксисом версию (у меня не было проблем с ее просмотром). Мне нужно сохранить AST, сгенерированный clang, в файл, а затем проанализировать его, что было бы трудно с информацией о цвете, оставшейся в.

Maou
источник
4
Стоит отметить, что >не генерирует вывод, он просто указывает оболочке, что вы хотите поместить вывод вашей clangкоманды в данный файл, а не в терминал. После этого вы просматриваете его способом, который не позволяет цветовые коды таким же образом. Если бы вы были catв файле, он работал бы так, как бы управлял терминал, и вы можете сделать lessто же самое с -Rфлагом.
Саммит
@ Scott - я не пытаюсь просмотреть вывод, я пытаюсь сохранить его в файл, не оставляя в информации о цвете, что сделало бы разбор файла излишне сложным.
Maou

Ответы:

54

Это не имеет ничего общего с кодовыми страницами / кодированием. Ваш вывод не простой текст. Он содержит такие последовательности, как [0;1;32m. Эти строки (перед каждым из них есть и не показанный символ [escape]) являются инструкциями для терминала для отображения текста, выделенного полужирным шрифтом, курсивом, различными цветами и т. Д. Это приводит к более легкому чтению вывода, если ваш терминал поддерживает это.

Должна быть возможность указать clang не пытаться украсить вывод, а вместо этого использовать обычный текст. Проверьте руководство. (У меня нет одной под рукой, поэтому я не могу сказать вам, какой будет правильная команда.)

Tonny
источник
15
Спасибо, это было причиной. Я пытался, clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txtкоторый дал мне правильный вывод.
Maou
9
Альтернативное исправление, если Clang достаточно хорошо себя ведет (чего, очевидно, нет, отправляет коды терминалов без проверки isatty(stdout)), - установить TERM(например,) dumb.
Тоби Спейт
4
Re "Это приводит к тому, что вывод будет проще для чтения, если ваш терминал его поддерживает.", Это, конечно, мнение. Это не всегда работает, например, когда приложение для раскрашивания выводит темно-синий текст на черном фоне :-(
jamesqf
4
Любое разумное программное обеспечение должно обнаружить, что его выходные данные перенаправляются в файл, и в этом случае отключить цвет.
nrrd
1
@ n0rd В идеале да, но я видел достаточно ситуаций, когда isattty () не давали false при перенаправленном выводе. А в некоторых случаях пользователь может захотеть перенаправить управляющие коды (например, для просмотра позже или передачи в netcat для просмотра в другой системе, просто для предоставления 2 вариантов использования). Поэтому попытайтесь угадать, но также позвольте пользователю включить / выключить его, отвергая предположение на случай, если оно ошибочно. Это было бы лучшим решением.
Тонни
12

В качестве альтернативы, вместо удаления цветов из вывода, вы можете просмотреть цветной вывод в вашем терминале, используя необработанную опцию less

less -r output.txt
987poiuytrewq
источник
2

Эти символы, например, [0;33mвыглядят как управление выводом терминала для меня. Они являются частью набора escape-последовательностей, которые часто используются для применения цветов к тексту в терминале. В исходном состоянии, как это, он также часто используется для применения цвета к самой подсказке bash. Вот то, что я использовал в .bashrcтечение многих лет на всех моих машинах:

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

(Большинство думает, что это некрасиво, но мне это нравится).

Посмотрите, сможете ли вы найти переключатель для удаления какой-либо цветовой кодировки или тому подобного из выходных данных ваших команд, и посмотрите, поможет ли это.

Ярмунд
источник
13
[...] «Похоже, контроль вывода bash для меня» Они не имеют ничего общего с bash. Это терминал для чего они нужны.
glglgl
1
Как сказал @glglgl, они не относятся к Bash, они связаны между собой xterm. Смотрите этот отличный ответ от ведущего разработчика xterm.
кот
@glglgl Хорошо, ответ отредактирован соответственно. Впервые я увидел это при переходе с fBSD на linux несколько лет назад, когда я тоже начал использовать bash, поэтому я подумал, что это продукт последнего.
Джармунд