Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm using the linux 'script' command http://www.linuxcommand.org/man_pages/script1.html to track some interactive sessions. The output files from that contain unprintable characters, including my backspace keystrokes.

Is there a way to tidy these output files up so they only contain what was displayed on screen?

Or is there another way to record an interactive shell session (input and output)?

share|improve this question

12 Answers 12

up vote 20 down vote accepted

If you want to view the file, then you can send the output through col -bp; this interprets the control characters. Then you can pipe through less, if you like.

col -bp typescript | less -R

On some systems col wouldn't accept a filename argument, use this syntax instead:

col -bp <typescript | less -R
share|improve this answer
    
on my system, col wouldn't accept a filename, so I did col -bp < typescript and got what I wanted. – Andrew Mar 19 '12 at 12:19

I used cat filename which removes control characters :-)

share|improve this answer
    
imo this is a nicer answer, since it really removes all the control characters. – Nathanael Farley Sep 23 '14 at 11:02
    
on OSX, cat does not remove colour control characters... – Nick Dec 10 '14 at 18:04

If you want to write the output to a file:

col -bp < typescript >>newfile

use unix2dos command to convert file to Windows format if you want

share|improve this answer
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed
share|improve this answer
    
I still need to figure out how, but this really works ;) – asdmin Feb 10 at 6:21
    
@asdmin - Basically, this echoes the output of the typescript to a perl program that removes certain control characters from the output, then pipes the output to the unix col command, whose -b option removes any "delete" key artifacts in the transcript. It then pipes the output to a text file. – Peter Nore Feb 10 at 9:57

For a large quantity of script output, I'd hack a perl script together iteratively. Otherwise hand edit with a good editor.

There is unlikely to be an existing automated method of removing control characters from script output in a way that reproduces what was displayed on the screen at certain important moments (such as when the host was waiting for that first character of some user input).

For example the screen might be blank except for Andrew $, if you then typed rm /* and pressed backspace twelve times (far more than needed), what gets shown on the screen at the end of that depends on what shell was running, what your current stty settings are (which you might change partway through a session) and probably some other factors too.

The above applies to any automated method of continuously capturing input and output. The main alternative is taking "screen shots" or cutting and pasting the screen at appropriate times during the session (which is what I do for user guides, notes for a day-log, etc).

share|improve this answer

An answer to the second part of my question is to use the logging facility in gnu screen: ^A H from within a running screen session. The documentation is at http://www.gnu.org/software/screen/manual/screen.html#Logging

share|improve this answer

I found the answer that dewtall provided to a similar question on the Unix board to be more effective at removing control characters from the output of script if you are in an environment where Perl is available to you.

dewtall's script:

#!/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;
}

To remove the control characters:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed
share|improve this answer

https://github.com/RadixSeven/typescript2txt was written to solve this problem.

It's been 4 years since I last updated/used it, but I don't remember doing anything fancy that shouldn't still work today.

share|improve this answer

If what you're after is to record your commands (e.g. to later turn them into a bash script), then a reasonable hack is to run script(1), then inside it run

bash -x

Afterwards grep the output file (usually "typescript") looking for lines starting with a "+". The regular expression ^\+ will do the trick.

share|improve this answer

col -bp processes the backspaces as desired (AFAIK). But it mangles the color escape sequences. It might be good to remove the color sequences first, then process the backspaces, if possible.

This is a very common need, and I'm surprised there are not more solutions to it. It is extremely common to script a session, then somebody has a need to review the procedure. You want to cut out all the little typing mistakes, and color escape sequences to create a "clean" script of the procedure for future reference. Simple ASCII text preferred. I think this is what is intended by "human readable", and it is a very reasonable thing to do.

share|improve this answer

dos2unix on the output will also do the trick

share|improve this answer
6  
Could you explain how to use it to accomplish the task? – Ben N Jan 5 at 23:05
    
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post. - From Review – Ramhound Jan 6 at 0:52

One other solution is to use strings which prints only printable characters from a file (or from standard input):

strings -n 1 filename

The -n 1 option sets the minimum length of the sequences to be preserved to one and thus makes sure even single printable characters surrounded by non-printable characters are preserved.

One possible downside of this approach is that strings adds line breaks between contiguous strings of printable characters. For instance a file with content

Foo<SOMECONTROLCHAR>Bar

(where <SOMECONTROLCHAR> is control character or any other non-printable character) would be returned as

Foo
Bar

Another issue brought up in the comments is that some sequences of control characters consist of a combination of both printable and non-printable characters and this approach would only remove part of those.

However, strings does a good job of removing control characters like the backspace mentioned in the question.

share|improve this answer
    
strings does not remove all non-printable characters. It identifies and prints sequences of printable characters. That is not the same thing. – Michael Kjörling Apr 1 at 15:13
    
@MichaelKjörling, you're right, by default strings only prints sequences of a minimum length of 4. I've corrected my answer by adding the -n 1 option which sets the minimum length to 1. Thanks for pointing this out. – justfortherec Apr 2 at 21:30
    
The answer still makes the same claim that strings removes all non-printable characters, so it is still wrong in the same way it was before the edit. It's also obviously broken because "some color code" (and control codes in general) often consist of both printable and non-printable characters. For example, a control code sequence to change the text color might be ESC[01;52m where ESC is the single escape character (byte value 27). Using strings as you suggest would leave [01;52m in the output, which is meaningless. – Michael Kjörling Apr 3 at 12:28
    
Good point, @MichaelKjörling. Especially the example with the color code was very unfortunate. Thanks for helping me to improve my answer. Do the edits address your concerns appropriately? strings might not do the same job as some of the other answers but IMHO it is a valid approach to solve the problem described in the question. – justfortherec Apr 4 at 20:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.