Cách dọn sạch đầu ra của lệnh 'script' linux


35

Tôi đang sử dụng lệnh 'script' của linux http://www.linuxcommand.org/man_pages/script1.html để theo dõi một số phiên tương tác. Các tệp đầu ra từ đó chứa các ký tự không thể in được, bao gồm cả tổ hợp phím backspace của tôi.

Có cách nào để dọn dẹp các tệp đầu ra này để chúng chỉ chứa những gì được hiển thị trên màn hình không?

Hoặc có cách nào khác để ghi lại phiên shell tương tác (đầu vào và đầu ra) không?


"Hoặc có cách nào khác để ghi lại phiên shell tương tác (đầu vào và đầu ra) không?" Bạn có biết asciinema.org ?
masterxilo

Câu trả lời:


34

Nếu bạn muốn xem tệp, thì bạn có thể gửi đầu ra qua col -bp; Điều này diễn giải các ký tự điều khiển. Sau đó, bạn có thể ống thông qua ít hơn, nếu bạn muốn.

col -bp typescript | less -R

Trên một số hệ thống colsẽ không chấp nhận đối số tên tệp, thay vào đó hãy sử dụng cú pháp này:

col -bp <typescript | less -R

1
trên hệ thống của tôi, colsẽ không chấp nhận tên tệp, vì vậy tôi đã làm col -bp < typescript và có được những gì tôi muốn.
Andrew

Không làm việc cho tôi, tranh giành một số đầu ra.
Alex

1
Trên hệ thống của tôi less -Rtự nó cung cấp đầu ra tốt hơn so với đường ống thông qua col -bpđầu tiên.
Brian Hawkins

@BrianHawkins Tôi đồng tình. Sử dụng col -bp <typescript | less -Rkhông hiển thị bảng điều khiển màu. Sử dụng less -R typescriptkhông hiển thị bảng điều khiển màu!
Trevor Boyd Smith

Điều này chỉ tốt nếu bạn muốn xem kịch bản tương tác less.
Trevor Boyd Smith

18
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed

Dưới đây là một số giải thích về đầu vào chuỗi tới perl:

  • s/pattern//gcó nghĩa là thực hiện thay thế trên toàn bộ ( gtùy chọn có nghĩa là thực hiện toàn bộ thay vì dừng trên chuỗi đầu vào thay thế đầu tiên)

Dưới đây là một số giải thích về mẫu regex:

  • \e khớp với ký tự điều khiển "thoát" đặc biệt (ASCII 0x1A)
  • ()là sự khởi đầu và kết thúc của một nhóm
  • |có nghĩa là nhóm có thể phù hợp với một trong N mẫu. trong đó các mẫu N
    • [^\[\]] hoặc là
    • \[.*?[a-zA-Z] hoặc là
    • \].*?\a
  • [^\[\]] có nghĩa
    • khớp với một tập hợp các ký tự KHÔNG trong đó các ký tự không phải là []
  • \[.*?[a-zA-Z] có nghĩa
    • khớp với một chuỗi bắt đầu bằng [sau đó thực hiện không tham lam .*?cho đến khi ký tự alpha đầu tiên
  • \].*?\a có nghĩa
    • khớp với một chuỗi bắt đầu ]sau đó thực hiện không tham lam .*?cho đến khi bạn nhấn ký tự điều khiển đặc biệt gọi là "ký tự cảnh báo (chuông)"

1
Tôi vẫn cần phải tìm ra cách, nhưng điều này thực sự hoạt động;)
asdmin

@asdmin - Về cơ bản, tiếng vọng này đầu ra của typescriptmột perlchương trình mà loại bỏ ký tự điều khiển nào đó từ đầu ra, sau đó ống đầu ra cho unix collệnh, có -btùy chọn loại bỏ bất kỳ "xóa" vật chủ chốt trong bảng điểm. Sau đó, nó dẫn đầu ra thành một tệp văn bản.
Peter Nore

Điều này làm xáo trộn đầu ra trong dòng đầu tiên của bản thảo cho tôi nhưng là câu trả lời tốt nhất.
Alex

Điều này dường như làm việc rất tốt với một số bản in; nó chắc chắn dễ đọc hơn đầu ra được tạo ra bởi câu trả lời được chấp nhận.
fakesad

câu trả lời huyền thoại!
zack

2

Đối với một số lượng lớn scriptđầu ra, tôi sẽ lặp đi lặp lại một tập lệnh perl. Nếu không thì chỉnh sửa bằng tay với một biên tập viên tốt.

Không có khả năng là một phương pháp tự động hiện có để loại bỏ các ký tự điều khiển khỏi scriptđầu ra theo cách tái tạo những gì được hiển thị trên màn hình tại một số thời điểm quan trọng (chẳng hạn như khi máy chủ đang chờ ký tự đầu tiên của một số đầu vào của người dùng).

Ví dụ: màn hình có thể trống ngoại trừ Andrew $, nếu sau đó bạn gõ rm /*và nhấn backspace mười hai lần (nhiều hơn mức cần thiết), những gì được hiển thị trên màn hình ở cuối tùy thuộc vào lớp vỏ nào đang chạy, sttycài đặt hiện tại của bạn là gì ( mà bạn có thể thay đổi giữa chừng trong một phiên) và có thể một số yếu tố khác nữa.

Những điều trên áp dụng cho bất kỳ phương pháp tự động nào liên tục nắm bắt đầu vào và đầu ra. Cách thay thế chính là chụp "ảnh chụp màn hình" hoặc cắt và dán màn hình vào những thời điểm thích hợp trong phiên (đó là những gì tôi làm cho hướng dẫn sử dụng, ghi chú cho nhật ký ngày, v.v.).



2

Tôi đã sử dụng cat filenameđể loại bỏ các ký tự điều khiển :-)


Imo đây là một câu trả lời đẹp hơn, vì nó thực sự loại bỏ tất cả các ký tự điều khiển.
Nathanael Farley

trên OSX, mèo không xóa các ký tự điều khiển màu ...
Nick

9
Trên thực tế, mèo hoàn toàn không loại bỏ các ký tự điều khiển, thay vào đó, nó đưa ra nguyên văn và thiết bị đầu cuối sẽ giải thích chúng. Điều đó có thể phù hợp với bạn nếu bản thảo của bạn ngắn so với bộ đệm đầu cuối của bạn và bạn chỉ có thể sao chép và dán từ thiết bị đầu cuối. Không tốt lắm nếu bản thảo của bạn lớn.
mc0e

1
Đã đồng ý. Điều này không loại bỏ bất cứ điều gì. Nó chỉ đơn giản là cho phép vỏ để giải thích chúng. Họ vẫn có mặt.
Kentgrav

2

Nếu những gì bạn đang theo là ghi lại các lệnh của bạn (ví dụ để sau đó biến chúng thành tập lệnh bash), thì một cách hack hợp lý là chạy script(1), sau đó bên trong nó chạy

bash -x

Sau đó grep, tệp đầu ra (thường là "bản thảo") tìm kiếm các dòng bắt đầu bằng "+". Các biểu thức thông thường ^\+sẽ làm các mẹo.


2

Nếu bạn muốn ghi đầu ra vào một tệp:

col -bp < typescript >>newfile

sử dụng lệnh unix2dos để chuyển đổi tệp sang định dạng Windows nếu bạn muốn


1
Trên Ubuntu 14.04, điều đó để lại rất nhiều rác ở đầu và cuối dòng. Khá dễ đọc, nhưng không thực sự sạch sẽ.
mc0e

2

col -bp xử lý các không gian phía sau như mong muốn (AFAIK). Nhưng nó xáo trộn các chuỗi thoát màu. Có thể tốt để loại bỏ các chuỗi màu trước, sau đó xử lý các khoảng trống, nếu có thể.

Đây là một nhu cầu rất phổ biến và tôi ngạc nhiên không có nhiều giải pháp cho nó. Nó là cực kỳ phổ biến để kịch bản một phiên, sau đó ai đó có nhu cầu xem lại thủ tục. Bạn muốn loại bỏ tất cả các lỗi đánh máy nhỏ và các chuỗi thoát màu để tạo ra một kịch bản "sạch" của quy trình để tham khảo trong tương lai. Văn bản ASCII đơn giản được ưa thích. Tôi nghĩ rằng đây là những gì được dự định bởi "con người có thể đọc được", và đó là một điều rất hợp lý để làm.


1

Tôi đã tìm thấy câu trả lời mà dewtall cung cấp cho một câu hỏi tương tự trên bảng Unix để có hiệu quả hơn trong việc loại bỏ các ký tự điều khiển khỏi đầu ra của tập lệnh nếu bạn ở trong môi trường có sẵn Perl cho bạn.

kịch bản của dewtall:

#!/usr/bin/perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}

Để xóa các ký tự điều khiển:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed


0

Tôi tìm thấy một cách tốt để làm điều đó. Trên hệ thống của tôi, các dòng đầu ra dài được rắc "^ M" (khoảng trống theo sau là trả về vận chuyển). "^ M" có thể được thay thế độc đáo bằng ký tự null "^ @", hoàn toàn không hiển thị khi bạn gửi tệp.

Tôi cũng nắm bắt thời gian, vì vậy để phát lại tập tin một cách hoàn hảo, tôi không thể đơn giản loại bỏ hoàn toàn "^ M" bằng cách sử dụng các lệnh bên dưới (vì scriptreplay đếm byte):

tr '\r' '\0' | sed 's/ \x0//g'

Tôi chạy lệnh script của tôi như thế này:

script -t -f session.log 2>timing

Vì vậy, những gì tôi làm sau đó là:

cat session.log | tr '\r' '\0' > typescript 
scriptreplay -t timing | sed 's/ \x0//g'

Chỉnh sửa đầu tiên (trước khi phát lại) giữ lại số byte trong tệp. Chỉnh sửa thứ hai (sau khi phát lại) được loại bỏ khoảng trắng ở những nơi ngẫu nhiên. (Lưu ý rằng theo mặc định scriptreplay tìm tệp đầu vào có tên "typecript", đó là lý do tại sao tôi không cung cấp nó sau "thời gian".)


-1

dos2unix trên đầu ra cũng sẽ thực hiện thủ thuật


7
Bạn có thể giải thích làm thế nào để sử dụng nó để hoàn thành nhiệm vụ?
Ben N

-1

Một giải pháp khác là sử dụng stringschỉ in các ký tự có thể in từ một tệp (hoặc từ đầu vào tiêu chuẩn):

strings -n 1 filename

Các -n 1tùy chọn thiết lập độ dài tối thiểu của chuỗi được bảo quản một và do đó làm cho các ký tự in chắc chắn thậm chí đơn bao quanh bởi các ký tự không in được bảo toàn.

Một nhược điểm có thể có của phương pháp này là stringsthêm các ngắt dòng giữa các chuỗi ký tự có thể in được. Ví dụ: một tệp có nội dung

Foo<SOMECONTROLCHAR>Bar

(trong đó <SOMECONTROLCHAR>ký tự điều khiển hoặc bất kỳ ký tự không in nào khác) sẽ được trả về là

Foo
Bar

Một vấn đề khác được đưa ra trong các ý kiến ​​là một số chuỗi ký tự điều khiển bao gồm sự kết hợp của cả hai ký tự có thể in và không in được và cách tiếp cận này sẽ chỉ loại bỏ một phần trong số đó.

Tuy nhiên, stringslàm tốt công việc loại bỏ các ký tự điều khiển như backspace được đề cập trong câu hỏi.


stringskhông loại bỏ tất cả các ký tự không in được. Nó xác định và in các chuỗi ký tự có thể in . Đó không phải là điều tương tự.
CVn

@ MichaelKjorling, bạn đúng, theo mặc định stringschỉ in các chuỗi có độ dài tối thiểu là 4. Tôi đã sửa câu trả lời của mình bằng cách thêm -n 1tùy chọn đặt độ dài tối thiểu thành 1. Cảm ơn bạn đã chỉ ra điều này.
justfortherec

Câu trả lời vẫn đưa ra cùng một tuyên bố stringsloại bỏ tất cả các ký tự không in được, do đó, nó vẫn sai theo cùng một cách trước khi chỉnh sửa. Nó rõ ràng cũng bị hỏng vì "một số mã màu" (và mã điều khiển nói chung) thường bao gồm cả các ký tự có thể in và không in được. Ví dụ, một chuỗi mã kiểm soát để thay đổi màu sắc văn bản có thể là ESC[01;52mnơi ESClà các ký tự thoát duy nhất (byte giá trị 27). Sử dụng stringsnhư bạn đề xuất sẽ để lại [01;52mtrong đầu ra, điều này là vô nghĩa.
CVn

Điểm tốt, @ MichaelKjorling. Đặc biệt là ví dụ với mã màu rất đáng tiếc. Cảm ơn đã giúp tôi cải thiện câu trả lời của tôi. Các chỉnh sửa giải quyết mối quan tâm của bạn một cách thích hợp? stringscó thể không làm công việc tương tự như một số câu trả lời khác nhưng IMHO đó là một cách tiếp cận hợp lệ để giải quyết vấn đề được mô tả trong câu hỏi.
justfortherec
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.