Mengapa dentang menghasilkan teks yang tidak dapat dipahami saat dialihkan?

20

Saya mencoba untuk menyimpan output dari perintah ke file. Perintahnya adalah:

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

Namun file output.txt yang dihasilkan ketika dibuka (oleh gedit dan jedit di ubuntu) memberi saya ini:

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

Kapan seharusnya terlihat seperti ini:

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

Saya pikir itu mungkin masalah penyandian, saya memeriksa penyandian file, file -bi output.txtyang menghasilkan text/plain; charset=us-ascii.

Saya pikir mungkin jika saya mengubah encoding ke utf-8 masalah akan diperbaiki jadi saya mencoba ini:

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

tapi itu tidak membuat perbedaan.

Apa yang bisa saya lakukan untuk mengatasi masalah ini?

Masalahnya bukan bahwa saya mencoba untuk melihat versi yang disorot sintaks (saya tidak punya masalah melihatnya di tempat pertama). Saya perlu menyimpan AST yang dihasilkan oleh dentang ke file dan kemudian menguraikannya, yang akan sulit dengan informasi warna yang tersisa.

maou
sumber
4
Perlu dicatat bahwa >tidak menghasilkan output, itu hanya menunjuk ke shell bahwa Anda ingin meletakkan output dari clangperintah Anda di file yang diberikan, daripada terminal itu. Setelah itu Anda melihatnya dengan cara yang tidak mengizinkan kode warna dengan cara yang sama. Jika Anda ke catfile itu akan berfungsi sebagai terminal akan mengambil alih, dan Anda dapat melakukan lesshal yang sama dengan -Rbendera.
Sammitch
@Scott - Saya tidak mencoba untuk melihat output, saya mencoba menyimpannya ke file tanpa meninggalkan informasi warna, yang akan membuat penguraian file menjadi rumit.
Maou

Jawaban:

54

Itu tidak ada hubungannya dengan codepages / encoding. Output Anda bukan teks biasa. Ini berisi urutan seperti [0;1;32m. String ini (ada, tidak ditampilkan, karakter [melarikan diri] juga sebelum masing-masing) adalah instruksi ke terminal untuk menampilkan teks tebal, miring, dalam berbagai warna, dll. Ini menghasilkan keluaran yang lebih mudah dibaca, jika terminal Anda mendukungnya.

Seharusnya ada opsi untuk memberi tahu dentang untuk tidak mencoba mempercantik hasil, tetapi gunakan teks biasa. Periksa manualnya. (Saya tidak punya satu berguna, jadi saya tidak bisa memberi tahu Anda apa perintah yang tepat.)

Tonny
sumber
15
Terima kasih, itu penyebabnya. Saya mencoba clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txtyang memberi saya hasil yang benar.
maou
9
Perbaikan alternatif, jika Dentang berperilaku cukup baik (yang jelas tidak, jika mengirim kode terminal tanpa memeriksa isatty(stdout)) adalah untuk diatur TERMke (misalnya) dumb.
Toby Speight
4
Re "Ini menghasilkan keluaran yang lebih mudah dibaca, jika terminal Anda mendukungnya.", Tentu saja, sebuah opini. Tidak selalu bekerja seperti itu, seperti misalnya ketika aplikasi pewarnaan mengeluarkan teks biru gelap di latar belakang hitam Anda :-(
jamesqf
4
Setiap perangkat lunak yang masuk akal harus mendeteksi bahwa outputnya sedang diarahkan ke file dan mematikan pewarnaan dalam kasus itu.
n0rd
1
@ n0rd Idealnya ya, tapi saya telah melihat cukup situasi di mana isattty () tidak diberikan false pada output yang dialihkan. Dan dalam beberapa kasus pengguna mungkin ingin kode melarikan diri dialihkan (misalnya untuk melihat nanti atau pipa ke netcat untuk melihat pada sistem lain, hanya untuk memberikan 2 kasus penggunaan). Jadi coba tebak, tetapi juga izinkan pengguna untuk mengaktifkannya / mematikan menimpa tebakan jika itu salah. Itu akan menjadi solusi terbaik.
Tonny
12

Sebagai alternatif, alih-alih menghapus warna dari output, Anda dapat melihat output berwarna di terminal Anda dengan menggunakan opsi mentah less

less -r output.txt
987poiuytrewq
sumber
2

Karakter-karakter itu, seperti [0;33mterlihat seperti kontrol keluaran terminal bagi saya. Mereka adalah bagian dari serangkaian urutan pelarian yang sering digunakan untuk menerapkan warna ke teks di terminal. Dalam keadaan mentah seperti ini, ia juga sering digunakan untuk mengaplikasikan warna ke bash prompt itu sendiri - Inilah yang telah saya gunakan .bashrcselama bertahun-tahun di semua mesin saya:

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

(Kebanyakan berpikir itu jelek, tapi saya suka).

Lihat apakah Anda dapat menemukan saklar untuk menghapus kode warna atau sejenisnya dari output perintah Anda dan lihat apakah itu membantu.

Jarmund
sumber
13
[...] "terlihat seperti kontrol output bash untuk saya" Mereka tidak ada hubungannya dengan bash. Ini adalah terminal untuk apa mereka.
glglgl
1
Seperti yang dikatakan @glglgl, mereka tidak spesifik untuk Bash, itu xtermhal yang terkait. Lihat jawaban luar biasa ini oleh pengembang utama xterm.
kucing
@glglgl Baiklah, jawab diedit sesuai. Saya pertama kali melihatnya ketika bermigrasi dari fBSD ke linux beberapa tahun yang lalu, yang juga ketika saya mulai menggunakan bash, jadi saya pikir itu adalah produk dari yang terakhir.
Jarmund