Чому кланг генерує нерозбірливий текст при переадресації?


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, згенерований клангом, у файл, а потім розібрати його, що було б складно з інформацією про кольори, що залишилася


4
Варто зауважити, що >не генерує вихід, він просто позначає оболонці, яку ви хочете поставити вихід вашої clangкоманди в даний файл, а не термінал. Після цього ви переглядаєте його таким чином, що не дозволяє кольорові коди таким же чином. Якби ви були до catфайлу, він працював би як термінал, і ви можете зробити lessтак само з -Rпрапором.
Саммітч



@Scott - Я не намагаюся переглянути результат, я намагаюся зберегти його у файл, не залишаючи інформацію про кольори, що зробило б необґрунтований аналіз файлу.
мау

Відповіді:


54

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

Повинна бути можливість сказати клангу не намагатися прикрасити вихід, а використовувати натомість звичайний текст. Перевірте посібник. (У мене немає однієї підруки, тому я не можу сказати вам, якою була б відповідна команда.)


15
Дякую, це було причиною. Я спробував, clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txtщо дало мені правильний вихід.
мау

9
Альтернативне виправлення, якщо Кланг досить добре поводиться (чого, очевидно, немає, якщо він надсилає термінальні коди без перевірки isatty(stdout)), слід встановити TERM(наприклад) dumb.
Toby Speight

4
Re "Це призводить до більш легкого для читання виводу, якщо ваш термінал підтримує його.", Тобто, звичайно, думка. Це не завжди працює так, як, наприклад, коли програма для забарвлення видає темно-синій текст на вашому чорному тлі :-(
jamesqf

4
Будь-який розумний фрагмент програмного забезпечення повинен виявити, що його вихід перенаправляється на файл і вимикає колоризацію в цьому випадку.
n0rd

1
@ n0rd В ідеалі так, але я бачив достатньо ситуацій, коли isattty () не було вказано помилковим на перенаправленому виході. І в деяких випадках користувач може захотіти, щоб коди евакуації були перенаправлені (наприклад, для перегляду пізніше або передачі в netcat для перегляду в іншій системі, просто щоб дати 2 випадки використання). Тому спробуйте здогадатися, але також дозвольте користувачеві вмикати та вимикати його, переосмислюючи здогадки у випадку, якщо він був неправильним. Це було б найкраще рішення.
Тонні

12

Крім того, замість того, щоб видаляти кольори з виводу, ви можете переглянути кольоровий вихід у своєму терміналі, використовуючи необроблений параметр less

less -r output.txt

2

Ті символи, як, наприклад, [0;33mвиглядають як управління термінальним виходом для мене. Вони є частиною набору послідовностей евакуації, які часто використовуються для нанесення кольорів на текст у терміналі. У такому сирому стані, як це, він також часто використовується для нанесення кольору на підказку 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. Це термінал, для чого вони призначені.
glglgl

1
Як сказав @glglgl, вони не є специфічними для Баша, вони xtermпов'язані між собою. Дивіться цю чудову відповідь провідного розробника компанії xterm.
кіт

@glglgl Добре, відповідь відповідним чином відредаговано. Я вперше побачив це, коли кілька років тому переходив з fBSD на Linux, що було і тоді, коли я почав використовувати bash, тому я подумав, що це продукт останнього.
Ярмунд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.