Recording & Sharing Terminal Sessions

This post describes how to make high quality recordings of terminal sessions that can be replayed in the terminal, or shared on the web. I'm defining high quality as recordings with zero typos, and relatively controlled timing between commands.

Jump to the end to see an example of the type of output I'm talking about.

Why? Videos and gifs take up a lot of disk space, don't age well as display technology improves, and are problematic for folks low vision requirements.

With the techniques below you can not only share examples of usage on your web pages, but within your tools themselves.

Goal(s)

  • record terminal session for demonstrating functionality
  • replay said recordings locally on a terminal
  • share said recordings online
  • have that recording look good

Bonus points:

  • editability
  • same file for terminal and web sharing
  • not having to do get everything perfect again when you need to record and updated version.

Tools

Its a live (itsalive)

same core idea as "doitlive" BUT with some additional functionality like being able to spit out a whole line, and drive interactive things like vim.

source code (GitLab)

What It Does

  • create a file of commands to be executed
  • have doitlive execute each of those commands as you type keys
  • always perfectly, and quickly typed
  • easy to control timing
  • allows you to pause and take control

    • thus actually doing it live in the middle of your script
    • can pause with the ##@pause comment which is useful immediately after a script that needs you to interact with it.
  • skip forward / back
  • allows you to spew out the rest of a line with CTRL+e
  • supports comments!

    • both comments for the viewer (start with #) & comments for the presenter (start with ##)
  • allows you to have scripted newlines with no input
  • Presenter View!!! you can see how you're progressing through your script, what came before, and what's coming up next. All in a separate terminal.

problems

  • it's actually executing the commands.
  • if you're in the wrong dir, don't have the commands the script needs installed, etc. it'll blow up
  • doesn't support comments, so you can't inline commentary for recordings
  • not shareable because others would need the same things installed, sometimes in the same places, and what you're doing may be specific to data on your system.
  • it doesn't directly handle, or record, interactive stuff So, for example, you can have it execute a script, but if you have to navigate around the resulting output with arrow keys, it won't record that. However, during playback it won't interfere with you doing that. Until the interactive script exits you are actually doing it live, not just pretending.
  • during playback you're literally just mashing keys. one keystroke per character output to the screen. So, if you're recording the playback of your recording (see below) you'll actually be recording gibberish. However, unless people are viewing the source code to your recording they won't be able to tell.

Notes

It will start playback in the default shell. If you want to specify a particular shell to playback with set the shell environment variable to the executable for that shell. E.g. SHELL=/opt/homebrew/opt/bash/bin/bash itsalive recording.sh

I keep my bash shell nice and minimal for recordings, but my day-to-day stuff is in fish.

doitlive

What it does

  • create a file of commands to be executed
  • have doitlive execute each of those commands as you type keys
  • always perfectly, and quickly typed
  • easy to control timing

Problems

  • Same as itsalive's problems.
  • because you're just mashing keys things that you may have pasted in real life are typed in character by character. this makes you look like an amazing typist, but it does take longer, because unlike itsalive there's no key combo to finish off the line in one stroke.
  • because of its lack of ability to pause & resume playback interactive things can be a little problematic.
  • because of its lack of presenter mode it is harder to time things well during recording.

Notes

It will start playback in the default shell. If you want to specify a particular shell to playback with set the shell environment variable to the executable for that shell. E.g. SHELL=/opt/homebrew/opt/bash/bin/bash doitlive recording.sh

I keep my bash shell nice and minimal for recordings, but my day-to-day stuff is in fish.

script (unix command)

old unix command BSD version (macOS) and Linux version are different. Linux needs scriptreplay. macOS version you can just point the same tool at a file and say -p to "play" it back.

What it does

  • records what you type and what came out
  • records the timings (or not)
  • the file could be run on the command line by others for downloadable examples.

    • I believe the format is the same on BSD and Linux

Problems

  • no way to convert these files directly to SVG or GIF or asciinema files (AFAIK)
  • it's nigh-impossible to get the timing right, and not show off bad / slow typing
  • editing of content or timing is not really possible

    • technically you can do it with teseq which is … not a joy

      • Recording of How to edit here (9 min)
      • script -> file -> teseq -> new file -> editor -> reseq
      • editing with teseq is doable, but the file format is not very easy to work with.
      • one thing it can do that's useful is edit timings

Asciinema

You can self-host (just needs the .js and .css files), or upload your recordings to Asciinema.org. Who knows how long Asciinema.org will continue to exist though.

What it does

  • records what you type and what came out
  • records the timings
  • stores a format that can be shared via a web page
  • stores in a format that can be replayed in a terminal

Problems

  • editing is not possible.

    • content or timing

Power-up Combo

how to make sweet looking recordings without typos or weird pauses.

  1. figure out exactly what commands you want to execute
  2. create a file itsalive (or doitlive) with those commands My recommendation is to use itsalive though because of the ability to record comments to yourself and the viewer. Note that it's not going to be recording timings, or edits or anything like that. It just records the commands you enter, and the file is only those commands, so it's really simple.
  3. add asciinema rec <filename> to the start of it so that it starts asciinema recording
  4. add a ##@pause comment in your script and then type ^d to exit asciinema without seeing the word exit typed out.
  5. launch itsalive myfile.sh or SHELL=/path/to/shell itsalive myfile.sh
  6. launch the presenter view in a separate terminal itsalive presenter_view
  7. click back into your original terminal but keep presenter view visible.
  8. Watch the presenter view not the real terminal. As you mash keys it'll show you your progress against the characters in the line. This makes it trivial to hit CTRL+e at the right point to make it look like you pasted, or to quickly finish off long lines for any other reason.
  9. mash keys / hit return at appropriate times to move through the steps of the script
  10. Party. Now you've got a shell script for itsalive and an asciinema file to do with as you want. You probably don't need the doitlive anymore, as it'll likely produce different results when run months, or years, in the future, but maybe it'll be useful to use as a starting point when you need to make a new recording for an updated version of the tool.

Real World Example

Here are the things I used to make some documentation for my git link-to-commit script.

What follows is the bash file that I ran with itsalive. Things of note:

  • Lines starting with ## are notes to myself because I'm watching the presenter_view as I run it.
  • The # lines are comments that will be included in the output.
  • The blank lines are significant, in that they actually cause a return to be emitted as if you hit return on the terminal.
  • I'm kicking off the asciinema recording from within the itsalive script so that the recording does not include me kicking off the itsalive playback.
  • The first ##@pause line is because the first invocation of git link-to-commit is going to require me to interact with a pull-down, so I need to pause the playback.
  • The second one is because I haven't figured out how to make it emit a CTRL+d to stop asciinema's recording. So I need to have interactive control over the terminal. I could have had it type exit but that would have been ugly.

Getting the timing right is still a bit of an art. The presenter_view really helped, but I needed to re-record a few times to get all the interactions and timings smooth enough. So, I just started the script off by having it delete any prior recordings (if present).

rm git-link-to-commit.asciinema 2>  /dev/null

## MOVE FAST AFTER THIS
asciinema rec git-link-to-commit.asciinema
git log -n1
# generate a link
## remember to mash then ^e when you get to the hash
git link-to-commit 2a15b8dea0ae606dedb8335e1c3106342e2d79ed
##@pause
##  ^r to RESUME playback
# skip the "choose a repo" step
## remember to mash then ^e when you get to the hash
git link-to-commit -o origin 2a15b8dea0ae606dedb8335e1c3106342e2d79ed
## EXIT ASCIINEMA
##@pause
## HIT ^d
## EXIT itsalive
exit

Demo

The final result.