我正在使用linux'script'命令 http://www.linuxcommand.org/man_pages/script1.html来跟踪一些交互式会话。该文件的输出文件包含不可打印的字符,包括我的退格键。
有没有办法整理这些输出文件,使它们仅包含屏幕上显示的内容?
还是有另一种方式来记录交互式Shell会话(输入和输出)?
我正在使用linux'script'命令 http://www.linuxcommand.org/man_pages/script1.html来跟踪一些交互式会话。该文件的输出文件包含不可打印的字符,包括我的退格键。
有没有办法整理这些输出文件,使它们仅包含屏幕上显示的内容?
还是有另一种方式来记录交互式Shell会话(输入和输出)?
Answers:
如果要查看文件,则可以通过输出发送输出col -bp
。这解释了控制字符。然后,您可以根据需要减少传输量。
col -bp typescript | less -R
在某些系统上col
不接受文件名参数,请改用以下语法:
col -bp <typescript | less -R
col
不接受文件名,所以我做了col -bp < typescript
,得到了我想要的。
less -R
,本身提供的输出要比col -bp
先行传递更好。
col -bp <typescript | less -R
不会显示彩色控制台。使用less -R typescript
会显示彩色控制台!
less
。
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed
这是输入到的字符串的一些解释perl
:
s/pattern//g
表示对整个g
输入字符串进行替换(该选项表示对整个字符串进行替换,而不是对第一个替换项停止)这是对正则表达式模式的一些解释:
\e
匹配特殊的“转义”控制字符(ASCII 0x1A)(
并且)
是一个小组的开始和结束|
表示该组可以匹配N个模式之一。N个模式在哪里
[^\[\]]
要么\[.*?[a-zA-Z]
要么 \].*?\a
[^\[\]]
手段
[
和]
\[.*?[a-zA-Z]
手段
[
然后进行非贪婪.*?
直到第一个字母字符\].*?\a
手段
]
然后进行非贪婪操作,.*?
直到您击中称为“警报(响铃)字符”的特殊控制字符为止typescript
到一个perl
程序,该程序从输出中删除某些控制字符,然后将输出通过管道传输到unix col
命令,该命令的-b
选项将删除脚本中的所有“删除”关键工件。然后,它将输出通过管道传输到文本文件。
对于大量的script
输出,我会迭代地一起破解一个perl脚本。否则,请使用出色的编辑器进行手动编辑。
现有的自动化方法不太可能以script
某种方式重现某些重要时刻(例如,主机在等待某些用户输入的第一个字符时)在屏幕上显示的内容,从而从输出中删除控制字符。
例如,除了Andrew $
,屏幕可能是空白的,如果您随后键入rm /*
并按了12次退格键(远远超过了所需的次数),则最后显示在屏幕上的内容取决于正在运行的Shell,当前stty
设置(您可能会在整个会话过程中进行更改)以及其他一些因素。
以上适用于连续捕获输入和输出的任何自动化方法。主要的替代方法是在会话期间的适当时间拍摄“屏幕快照”或剪切和粘贴屏幕(这是我为用户指南所做的操作,为日间日志做的记录等)。
我问题的第二部分的答案是^A H
在运行屏幕的会话中使用gnu屏幕中的日志记录工具。该文档位于http://www.gnu.org/software/screen/manual/screen.html#Logging
我用cat filename
它删除控制字符:-)
我发现,如果您处于Perl可用的环境中,那么dewtall提供给Unix板上类似问题的答案可以更有效地从脚本输出中删除控制字符。
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;
}
删除控制字符:
./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed
编写https://github.com/RadixSeven/typescript2txt即可解决此问题。
自从我上次更新/使用它已经有4年了,但是我不记得做过什么现在还不能正常工作的幻想。
我找到了一个很好的方法。在我的系统上,长的输出行上撒有“ ^ M”(空格后跟回车符)。可以用空字符“ ^ @”很好地替换“ ^ M”,当您对文件进行分类时,它根本不会显示。
我也捕获时间,因此为了完美地重放文件,我不能简单地使用下面的命令完全删除“ ^ M”(因为scriptreplay计算字节):
tr '\r' '\0' | sed 's/ \x0//g'
我这样运行我的脚本命令:
script -t -f session.log 2>timing
因此,我之后要做的是:
cat session.log | tr '\r' '\0' > typescript
scriptreplay -t timing | sed 's/ \x0//g'
第一次编辑(重播之前)保留文件中的字节数。第二个编辑(在重播之后)在随机的地方消除了空白。(请注意,默认情况下scriptreplay会查找名为“ typescript”的输入文件,这就是为什么我在“ timing”之后没有提供输入文件的原因。)
另一种解决方案是使用strings
仅打印文件(或标准输入)中的可打印字符的解决方案:
strings -n 1 filename
该-n 1
选项将要保留的序列的最小长度设置为1,从而确保即使保留了由不可打印字符包围的单个可打印字符。
这种方法的一个缺点是,strings
在可打印字符的相邻字符串之间添加了换行符。例如包含内容的文件
Foo<SOMECONTROLCHAR>Bar
(其中<SOMECONTROLCHAR>
控制字符或其他任何不可打印的字符)将返回为
Foo
Bar
评论中提出的另一个问题是,控制字符的某些序列由可打印字符和不可打印字符的组合组成,这种方法只会删除其中的一部分。
但是,strings
在删除问题中提到的退格等控制字符方面做得很好。
strings
不会删除所有不可打印的字符。它标识并打印可打印字符的序列。那不是同一回事。
strings
仅打印最小长度为4的序列。我已通过添加-n 1
将最小长度设置为1 的选项来更正我的答案。感谢您指出这一点。
strings
删除所有不可打印的字符相同,因此以与编辑前相同的方式仍然是错误的。由于“某些颜色代码”(通常是控制代码)通常由可打印字符和不可打印字符组成,因此它显然也被破坏了。例如,一个控制码序列对改变的文本颜色可以是ESC[01;52m
其中ESC
是单转义字符(字节值27)。strings
如您建议的那样使用将保留[01;52m
在输出中,这毫无意义。
strings
可能无法与其他答案做同样的工作,但恕我直言,这是解决问题中所述问题的有效方法。