111

Is there some way of saving all the terminal output to a file with a command?

  • I'm not talking about redirection command > file.txt
  • Not the history history > file.txt, I need the full terminal text
  • Not with hotkeys !

Something like terminal_text > file.txt

5 Answers5

141

You can use script. It will basically save everything printed on the terminal in that script session.

From man script:

script makes a typescript of everything printed on your terminal. 
It is useful for students who need a hardcopy record of an 
interactive session as proof of an assignment, as the typescript file 
can be printed out later with lpr(1).

You can start a script session by just typing script in the terminal, all the subsequent commands and their outputs will all be saved in a file named typescript in the current directory. You can save the result to a different file too by just starting script like:

script output.txt

To logout of the script session (stop saving the contents), just type exit.

Here is an example:

$ script output.txt
Script started, file is output.txt

$ ls
output.txt  testfile.txt  foo.txt

$ exit
exit
Script done, file is output.txt

Now if I read the file:

$ cat output.txt

Script started on Mon 20 Apr 2015 08:00:14 AM BDT
$ ls
output.txt  testfile.txt  foo.txt
$ exit
exit

Script done on Mon 20 Apr 2015 08:00:21 AM BDT

script also has many options e.g. running quietly -q (--quiet) without showing/saving program messages, it can also run a specific command -c (--command) rather than a session, it also has many other options. Check man script to get more ideas.

SlavaSt
  • 125
heemayl
  • 56,300
  • 4
    Can it be invoked after the fact? (i.e. At the end of a session) Or does it have to be invoked before the content you want logged? – voices May 15 '16 at 16:02
  • @tjt263 It has to be invoked before the contents you want to be saved.. – heemayl May 15 '16 at 16:07
  • 9
    Damn. That's a shame. I don't usually know I want it until afterwards. – voices May 15 '16 at 17:09
  • @tjt263 you could put it inside your .bashrc and append everything into /tmp. – phil294 Jul 05 '17 at 00:38
  • 3
    To export it retroactively, try Terminal menu -> Shell -> Export text as, like here: mactricksandtips.com/2013/04/save-terminals-text-output.html – Magne Sep 22 '17 at 11:23
  • Thanks. This saved my day. But I had to use script -c "rails runner -e development lib/scripts/my_script.rb" report.txt because just using script then ran the rails runner in script session didn't wrote everything in the output file. Reference: https://askubuntu.com/a/715798/428475 – Jignesh Gohel Apr 20 '18 at 15:45
  • 4
    @Magne you should note in your comment that it is specific to the terminal utility in Mac. gnome-terminal, for one, does not have that menu, so we should assume that other linux terminal windows won't have it either. – maxwell Apr 15 '20 at 15:03
  • @maxweel thanks for pointing that out. I cannot edit my comment now, but I think your comment serves as that note now. – Magne Apr 15 '20 at 19:31
24

I too faced the same problem and after some search came up with this solution:

Add to your .bash_aliases this:

# Execute "script" command just once
smart_script(){
    # if there's no SCRIPT_LOG_FILE exported yet
    if [ -z "$SCRIPT_LOG_FILE" ]; then
        # make folder paths
        logdirparent=~/Terminal_typescripts
        logdirraw=raw/$(date +%F)
        logdir=$logdirparent/$logdirraw
        logfile=$logdir/$(date +%F_%T).$$.rawlog
    # if no folder exist - make one
    if [ ! -d $logdir ]; then
        mkdir -p $logdir
    fi

    export SCRIPT_LOG_FILE=$logfile
    export SCRIPT_LOG_PARENT_FOLDER=$logdirparent

    # quiet output if no args are passed
    if [ ! -z "$1" ]; then
        script -f $logfile
    else
        script -f -q $logfile
    fi

    exit
fi

}

Start logging into new file

alias startnewlog='unset SCRIPT_LOG_FILE && smart_script -v'

Manually saves current log file: $ savelog logname

savelog(){ # make folder path manualdir=$SCRIPT_LOG_PARENT_FOLDER/manual # if no folder exists - make one if [ ! -d $manualdir ]; then mkdir -p $manualdir fi # make log name logname=${SCRIPT_LOG_FILE##/} logname=${logname%.} # add user logname if passed as argument if [ ! -z $1 ]; then logname=$logname'_'$1 fi # make filepaths txtfile=$manualdir/$logname'.txt' rawfile=$manualdir/$logname'.rawlog' # make .rawlog readable and save it to .txt file cat $SCRIPT_LOG_FILE | perl -pe 's/\e([^\[\]]|[.?[a-zA-Z]|].?\a)//g' | col -b > $txtfile # copy corresponding .rawfile cp $SCRIPT_LOG_FILE $rawfile printf 'Saved logs:\n '$txtfile'\n '$rawfile'\n' }

And to the end of your .bashrc file add this:

smart_script

After you've done this, "script" command will be executed once in every terminal session, logging everything to ~/Terminal_typescripts/raw.

If you want, you can save current session log after the fact (in the end of the session) by typing savelog or savelog logname – this will copy current raw log to ~/Terminal_typescripts/manual and also create readable .txt log in this folder.  (If you forget to do so, raw log files will still be in their folder; you'll just have to find them.)  Also you may start recording to a new log file by typing startnewlog.

There will be a lot of junk log files, but you can clean old ones from time to time, so it's not a big problem.

(Based on https://answers.launchpad.net/ubuntu/+source/gnome-terminal/+question/7131 , https://askubuntu.com/a/493326/473790 )

alexpad
  • 341
  • Why do you need the 'exit' command after you started the logging? – Danijel Sep 05 '19 at 07:44
  • Seems like calling "script" command from the .bash_profile on Mac OSX has some strange effect on the shell. Do you know if this should work on OSX? – Danijel Sep 05 '19 at 07:58
  • @Danijel can you describe "some strange effect" you mentioned? This would help others to help you. – Stéphane Gourichon Nov 22 '19 at 16:00
  • I can't remember any more :-(, sorry. – Danijel Nov 25 '19 at 08:06
  • @Danijel The "exit" command is needed because if you don't, you'll have to type exit (or ctlr+d) twice in every terminal tab you have open, instead of the normal once. The first exit will exit the "script" session, and the second will exit your bash session and close the terminal tab (if you have auto-close enabled upon exit). – Scott Dec 15 '19 at 17:21
  • Any solution about using vim (or some another interactive editor or alike) fills the log file with a lot of junk? – kaki gadol Jul 15 '20 at 19:59
  • @kakigadol Im wondering the same.. did u find any solution to this issue? alexpad maybe some input on this? – Nerotix Dec 10 '20 at 10:52
  • 1
    yes, I found a great project named asciinema it solves most of the problems https://asciinema.org/ – kaki gadol Dec 27 '20 at 15:40
4

In the following steps, run xrdb ~/.Xressources after modifying the X-resources file, then open a new terminal to test the changes.

XTerm

Mouse: Hold CtrlLeft-mouse-click. The "Main Options" menu shows up. Select "Print-All Immediately" and release. An XTerm[date] file with the terminal contents has been created in your home directory.

Keyboard shortcut: To bind the action to CtrlShifty, add to your ~/.Xresources file:

XTerm*vt100.Translations: #override\
    Ctrl Shift <Key> y: print-immediate()

Setting the path: printFileImmediate sets the prefix of the dumped file. Useful to specify the path of the dumped file. For example, to dump /home/user/dumps/xt[date] files,

XTerm*printFileImmediate: /home/user/dumps/xt

Urxvt

Keyboard shortcut: Include in ~/.Xresources:

URxvt.print-pipe: cat > $HOME/scrollback

Binds to Ctrl+Print or Shift+Print.

Other terminals

Not all of them can do it; check their manual page or menu options.

Beyond script, a terminal-agnostic solution is to use a multiplexer.

In Tmux, it's a matter of running its internal command

capture-pane -S - ; save-buffer scrollback-file

This in .tmux.conf would bind it to Ctrl+bCtrl+s:

bind C-s capture-pane -S - \; save-buffer $HOME/scrollback
Quasímodo
  • 18,865
  • 4
  • 36
  • 73
2

nhi will perfectly solve your problem. This tool automatically captures all potentially useful information about each executed command (as well as its output).

With nhi you can easily retrieve any shell session (or terminal output) in its entirety, or only a part of shell session, by using an advanced querying mechanism provided by nhi.

You can think of nhi as a greatly enhanced history.

Note:

I am the creator of this tool. If you have questions, please feel free to ask.

  • I am looking for something like this but I used cygwin, MacOS, and Ubuntu. I would like to try this on Ubuntu but can you elaborate on what changes you made to bash? Is it possible to use it with stock bash with limited functionality? – Miserable Variable Mar 29 '22 at 01:50
  • @MiserableVariable Bash and zsh binaries since ubuntu 21.04 are for some reason stripped from variable addresses which are required by nhi. I didn't change bash and zsh binaries at all. My bash and zsh binaries are exactly the same as in other distros (ubuntu made some unusual changes to their binaries). – strang1ato Mar 30 '22 at 16:26
0

For xfce4-terminal use the accels.scm file.

For instance, to reassign Ctrl-Shift-s from 'set title' to 'save contents' Open to edit: ~/.config/xfce4/terminal/accels.scm

Then search for 'save-contents' and modify the line as follows:

(gtk_accel_path "<Actions>/terminal-window/save-contents" "<Primary><Shift>s")
; This will map 'save the entire scrollback buffer to a file' to the Left_Ctrl-Shift-s keystrokes.

; NOTE: commented lines start with a ;

xfce4-terminal has a menu layout similar to the mac terminal answer above. Within an xfce4-terminal select 'Terminal, Save contents..' or simply Left_Ctrl-Shift-s.

A filemanager will open to allow you to select where to save the file containing the screen buffer output.

MC68020
  • 7,981
1of7
  • 11
  • 3