Tại sao clang tạo ra văn bản khó hiểu khi được chuyển hướng?


20

Tôi đang cố gắng lưu đầu ra của một lệnh vào một tập tin. Lệnh là:

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

Tuy nhiên, tệp output.txt kết quả khi được mở (bởi gedit và jedit trên ubfox) mang lại cho tôi điều này:

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

Khi nó thực sự trông như thế này:

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

Tôi nghĩ rằng nó có thể là một vấn đề về mã hóa, tôi đã kiểm tra mã hóa của tập tin, file -bi output.txtmà đầu ra text/plain; charset=us-ascii.

Tôi nghĩ có lẽ nếu tôi thay đổi mã hóa thành utf-8 thì vấn đề sẽ được khắc phục nên tôi đã thử điều này:

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

nhưng nó không tạo ra sự khác biệt.

Tôi có thể làm gì để giải quyết vấn đề này?

Vấn đề không phải là tôi đang cố gắng xem phiên bản được tô sáng cú pháp (tôi không gặp vấn đề gì khi xem nó ở vị trí đầu tiên). Tôi cần lưu AST được tạo bởi clang vào một tệp và sau đó phân tích nó, điều này sẽ gây khó khăn với thông tin màu còn lại.


4
Điều đáng chú ý là >không tạo ra đầu ra, nó chỉ đơn giản chỉ định trình bao mà bạn muốn đặt đầu ra của clanglệnh trong tệp đã cho, thay vì sau đó là terminal. Sau đó, bạn đang xem nó theo cách không cho phép mã màu theo cùng một cách. Nếu bạn vào cattập tin, nó sẽ hoạt động như thiết bị đầu cuối sẽ tiếp quản và bạn có thể thực lesshiện tương tự với -Rcờ.
Sammitch



@Scott - Tôi không cố xem đầu ra, tôi đang cố lưu nó vào tệp mà không để lại thông tin màu, điều này sẽ khiến việc phân tích tệp phức tạp không cần thiết.
maou

Câu trả lời:


54

Nó không có gì để làm với tiền mã hóa / mã hóa. Đầu ra của bạn không phải là văn bản đơn giản. Nó chứa các trình tự như thế [0;1;32m. Các chuỗi này (có một ký tự, không hiển thị, [thoát] trước mỗi chuỗi này) là các hướng dẫn đến thiết bị đầu cuối để hiển thị văn bản in đậm, in nghiêng, trong các màu khác nhau, v.v. Điều này dẫn đến đầu ra dễ đọc hơn, nếu thiết bị đầu cuối của bạn hỗ trợ nó

Nên có một tùy chọn để nói với clang không cố gắng làm đẹp đầu ra, mà sử dụng văn bản đơn giản để thay thế. Kiểm tra hướng dẫn. (Tôi không có một tiện dụng, vì vậy tôi không thể cho bạn biết lệnh thích hợp sẽ là gì.)


15
Cảm ơn, đó là nguyên nhân. Tôi đã thử clang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txtmà cho tôi đầu ra chính xác.
maou

9
Một cách khắc phục khác, nếu Clang hoạt động khá tốt (điều này rõ ràng là không, nếu nó gửi mã đầu cuối mà không kiểm tra isatty(stdout)) sẽ được đặt TERMthành (ví dụ) dumb.
Toby Speight

4
Re "Điều này dẫn đến đầu ra dễ đọc hơn, nếu thiết bị đầu cuối của bạn hỗ trợ nó.", Tất nhiên, đó là một ý kiến. Không phải lúc nào cũng hoạt động như vậy, ví dụ như khi ứng dụng tô màu xuất ra văn bản màu xanh đậm trên nền đen của bạn :-(
jamesqf

4
Bất kỳ phần mềm hợp lý nào cũng sẽ phát hiện ra rằng đầu ra của nó đang được chuyển hướng đến tập tin và tắt màu trong trường hợp đó.
n0rd

1
@ n0rd Lý tưởng là có, nhưng tôi đã thấy đủ các tình huống trong đó isattty () không được cung cấp sai trên đầu ra được chuyển hướng. Và trong một số trường hợp, người dùng có thể muốn chuyển mã thoát (ví dụ để xem sau hoặc chuyển sang netcat để xem trên hệ thống khác, chỉ để đưa ra 2 trường hợp sử dụng). Vì vậy, hãy thử đoán, nhưng cũng cho phép người dùng bật / tắt ghi đè lên dự đoán trong trường hợp nó sai. Đó sẽ là giải pháp tốt nhất.
Tonny

12

Ngoài ra, thay vì loại bỏ màu khỏi đầu ra, bạn có thể xem đầu ra màu trong thiết bị đầu cuối của mình bằng cách sử dụng tùy chọn thô của less

less -r output.txt

2

Những ký tự đó, chẳng hạn như [0;33mtrông giống như điều khiển đầu ra đầu cuối đối với tôi. Chúng là một phần của tập hợp các chuỗi thoát thường được sử dụng để áp dụng màu cho văn bản trong thiết bị đầu cuối. Ở trạng thái thô như thế này, nó cũng thường được sử dụng để áp dụng màu cho dấu nhắc bash - Đây là những gì tôi đã sử dụng trong .bashrcnhiều năm trên tất cả các máy của mình:

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

(Hầu hết nghĩ rằng nó xấu, nhưng tôi thích nó).

Xem nếu bạn có thể tìm thấy một công tắc để loại bỏ bất kỳ mã màu hoặc tương tự từ đầu ra của các lệnh của bạn và xem nếu điều đó giúp.


13
[...] "Trông giống như kiểm soát đầu ra của bash đối với tôi" Chúng không liên quan gì đến bash. Đây là thiết bị đầu cuối những gì họ đang làm.
glglgl

1
Như @glglgl đã nói, chúng không phải là đặc trưng của Bash, chúng là một xtermthứ liên quan. Xem câu trả lời tuyệt vời này của nhà phát triển chính của xterm.
mèo

@glglgl Được rồi, trả lời chỉnh sửa cho phù hợp. Lần đầu tiên tôi nhìn thấy nó khi chuyển từ fBSD sang linux vài năm trước, đó cũng là khi tôi bắt đầu sử dụng bash, vì vậy tôi nghĩ rằng nó là một sản phẩm sau này.
Jarmund
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.