Record, share or stream terminal sessions with asciinema

Page contents

Sharing a terminal session has been a rare but annoying need of many administrators and software engineers, often having to resort to recording videos or screen sharing as a stop-gap measure - but there are better open source tools for the job.

Why asciinema?

Compared to screen recordings, asciinema has several advantages. The main one is that it stores terminal contents as text, making recordings much smaller and keeping outputs clearly visible at any scale and screen size during playback.

Recordings also stay interactive during playback, allowing users to pause in the middle and copy any text they want out of the playback.

Basic usage

If you only want to record a single command and its output, use the -c flag:

asciinema rec -c "echo 'hello world'" demo.cast

Alternatively, you can also record a session of multiple commands interactively. Start by running:

asciinema rec recording.cast

Now type anything you like, then press ctrl+D to stop recording.

Your inputs and the command output, as well as the styling and colors of your terminal are now saved in the file recording.cast.


You can play it back on the terminal with:

asciinema play recording.cast

That's it! The recording.cast file can easily be shared. Larger files often compress very well with zip since they are text-based, allowing to send them over size-restricted communication platforms like messengers or email.

Adjusting recordings

A recording maintains the timing of inputs and outputs, possibly leading to inconsistent typing speeds and idle times between commands. The idle times can be limited to a maximum value with the --idle-time-limit flag, but will still be inconsistent within the allowed range.


For high quality recordings with consistent typing speeds and idle times, you can "fake" an interactive session with a script that first writes the prompt, then "types" the command and finally actually runs it.


It may look something like this:


script.sh

#!/bin/bash

prompt() {
	printf '%s' 'user@host$ '
}
prompt

cmd() {
    local cmd="$1"
    for ((i=0; i<${#cmd}; i++)); do
        printf "%s" "${cmd:$i:1}"
        sleep 0.15
    done
    printf "\n"
    sleep 0.5
	eval "$cmd"
	prompt
}

cmd "echo hello world"
sleep 1

cmd "ls -l"
sleep 1

The script uses a helper function prompt() to print a fake prompt before and after commands, mimicking a real terminal shell. Typing and running the command is handled by cmd(), which contains two important sleep calls: The one within the loop is important to make the typing seem more human, while the second one before running the command exists to give readers later a chance to read the typed command before output potentially scrolls the line away. Adjust each to suit your taste.


You can get a recording using the script with:

asciinema rec -c ./script.sh demo.cast

The resulting recording will behave like any interactive recording. You may need to adjust the prompt() function to include escape sequences for colors or text effects to make it feel more realistic.

Careful with business recordings!

A point often overlooked when recording terminal sessions is privacy. Asciinema makes it very easy to record any terminal interaction, but the recording may fall under privacy laws like GDPR if they contain data like ip addresses from logs or email addresses.

In the eyes of the law, sharing the personal data or the recording containing it is essentially the same, so recordings must be protected and shared only with the necessary recipients.

Asciinema provides a great public server for uploading and streaming, but commercial users should avoid it for exactly these reasons.

To help practical adoption, we offer asciinema-server based and alternative sharing and streaming options in the coming paragraphs.

Using asciinema server

To share recordings or streams directly over a web interface, asciinema offers a server component. Private users can freely use the public instance hosted at asciinema.org directly, but businesses should host their own instance to comply with privacy laws.


If you host your own instance, make sure to set ASCIINEMA_SERVER_URL in your terminal or .bashrc, so users can't accidentally upload to the wrong server.


To share recordings, you will need to create an account on your desired instance, then authenticate your device:

asciinema auth

Open the printed link in a web browser to sign in.

Now you can easily upload recordings:

asciinema upload my_recording.cast

You will see a link to the recording. By default, anybody with that link can view your recording in a browser, but you can change access from the web ui.


Streaming live terminal sessions is also very straight-forward through an asciinema server. Simply run:

asciinema stream -r

And your stream is live! A link for web viewers will be printed to the terminal, then the sesion behaves just like recording, streaming every keystroke and output live to viewers until you hit ctrl+d.

Sharing recordings without an asciinema server

Without an asciinema server instance, you can also share recordings with others.

The most obvious solution is to use shared network storage or send it through filesharing websites.

If you prefer using a publicly available server, a vps with a webserver can be turned into a host for recordings.

For example, you could host your recording my_recording.cast as a simple file on an http server and play it directly from there:

asciinema play http://example.com/my_recording.cast

For added security, consider configuring SSL and basicauth for the server, both are supported by ´asciinema as well:

asciinema play 'https://user:password@example.com/my_recording.cast'

If the recording needs to be available to viewers directly in the browser, host a tiny website alongside it:

<!DOCTYPE html>
<html>
<head>
  <title>Embedded asciinema recording</title>
  <link rel="stylesheet" type="text/css" href="/asciinema-player.css" />
</head>
<body>
  <div id="demo"></div>
  <script src="/asciinema-player.min.js"></script>
  <script>
    AsciinemaPlayer.create(
      '/my-recording.cast',
      document.getElementById('demo')
    );
  </script>
</body>
</html>

Check the latest asciinema player release for the asciinema-player.min.js and asciinema-player.css files.

Streaming without an asciinema server

Streaming also doesn't necessarily require an asciinema server instance.

You can start a local stream directly:

asciinema stream -l

This opens a stream on 127.0.0.1 and a random port. You can alternatively set the host to 0.0.0.0 to make it available to all machines in your LAN:

asciinema stream -l 0.0.0.0:8080

Now all LAN members can view your stream by pointing their browser to http://<your_ip>:8080/.

This is of course missing authentication, so only do it in LAN networks you trust, or run your stream on localhost and use a reverse proxy to add SSL and basicauth for added security.


A local stream can easily be turned into a remotely available stream by using existing VPNs or tunneling tools like zrok or ngrok to forward just the application to a publicly available endpoint.


As a last option, you could even forward the stream through an SSH server without any additional setup (assuming it is configured with GatewayPorts yes):

ssh -R 8080:127.0.0.1:8080 user@example.com

Now the local stream on 127.0.0.1:8080 is available through the online server at example.com:8080 until you stop the ssh command with ctrl+c.


Consider forwarding to a localhost port on the server and use a reverse proxy setup to add SSL encryption and authentication.

More articles

Building an OPNsense environment on KVM

Easy setup for test sandboxes and production workloads alike

Using PostgreSQL as a MongoDB drop-in replacement with FerretDB

Combining MongoDB queries with reliable PostgreSQL storage

Understanding hyperconverged infrastructure

...and how it compares to real cloud stacks