90

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

4

4 Answers 4

116

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.

8
  • 1
    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, 2016 at 16:02
  • @tjt263 It has to be invoked before the contents you want to be saved..
    – heemayl
    May 15, 2016 at 16:07
  • 6
    Damn. That's a shame. I don't usually know I want it until afterwards.
    – voices
    May 15, 2016 at 17:09
  • 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, 2017 at 11:23
  • 2
    @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, 2020 at 15:03
21

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 )

8
  • Why do you need the 'exit' command after you started the logging?
    – Danijel
    Sep 5, 2019 at 7: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 5, 2019 at 7:58
  • @Danijel can you describe "some strange effect" you mentioned? This would help others to help you. Nov 22, 2019 at 16:00
  • I can't remember any more :-(, sorry.
    – Danijel
    Nov 25, 2019 at 8:06
  • 1
    yes, I found a great project named asciinema it solves most of the problems asciinema.org
    – kaki gadol
    Dec 27, 2020 at 15:40
2

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
0

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.

2
  • 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? Mar 29 at 1: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 at 16:26