asciinema-rec_script
asciinema-rec_script copied to clipboard
Record 💭 comments and ❯ commands from from shell scripts in addition to their output.
asciinema-rec_script
Record 💭 comments and ❯ commands from from shell scripts in addition to their output.
This is done by building a version of the original script that surfaces all the comments and commands by also echoing them to the screen.
Then passing that augmented script to asciinema's rec --command command.
Motivation
The asciinema tool is an awesome terminal session recorder.
And it has a rec [filename] command with a -c --command=<command> option.
This specifies a command to record (other than the default of $SHELL)
So given an (executable) script screencasts/demo-date_maths:
#!/usr/bin/env bash
## Date maths
# The `date` command can be used to retrieve the:
# * *day of the week* using the `%l` option
day_of_the_week=$(date +%l)
# * *hour of the day* using the `%u` option
hour=$(date +%u)
# Now, can you guess what we're going to do with those two numbers?
# 🤔...
sleep 3
# We're going to add them together!
echo $((day_of_the_week + hour))
We can use asciinema's rec to make a recording:
asciinema rec --command screencasts/demo-date_maths
However that recording is going to lose a bunch of context from the script and end up looking something like this:

If, however we instead used this command:
asciinema-rec_script screencasts/demo-date_maths
Without any effort we can end up with a recording like this:

Getting Started
Installation:
Place asciinema-rec_script somewhere in your $PATH.
Requirements:
- asciinema (installation)
- bash
- (optional) bat (installation)
- A
catclone to provide syntax highlighting
- A
Example Usages:
asciinema-rec_script ./screencasts/demo-date_maths- When called with no extra arguments, the tool will pass
asciinema reca filename of./screencasts/demo-date_maths.castto place the recording in - (Nb. the filename is derived from the source script by attaching a
.castextension.)
- When called with no extra arguments, the tool will pass
./screencasts/demo-date_maths.asc- Will take advantage of the shebang line #!/usr/bin/env asciinema-rec_script in the
.ascscript - (ie. allowing the input script to be run as its own command, without having to pass it as an argument to
asciinema-rec_script)
- Will take advantage of the shebang line #!/usr/bin/env asciinema-rec_script in the
./screencasts/demo-date_maths.asc --- When called with
--the tool will allowasciinema recto receive no additional arguments - (ie. allowing it to maintain its default behaviour of uploading screencasts to https://asciinema.org)
- When called with
./screencasts/demo-date_maths.asc --help- Will also pass any additional arguments it gets to
asciinema rec - (so eg.
--helpwill show all the asciinema rec [options])
- Will also pass any additional arguments it gets to
SLEEP=0 ./screencasts/demo-bash_functions.asc- (env vars can be passed into the script in the regular way)
- (to eg set
PROMPT="$ ",PROMPT_PAUSE=5)
bash ./screencasts/demo-date_maths.asc- Nb. It should also be possibe to execute the
.ascscript in your $SHELL as a regular bash script - (Maintaining this compatability means that the
.ascfile won't require any special commands that a regular shell script wouldn't already have in it. Which hopefully results in regular shell scripts resulting in half-decent looking recordings.)
- Nb. It should also be possibe to execute the
(Nb. the .asc extension ("ASCiinema") is not strictly necessary, but gives some uniformity.)
How it works
asciinema-rec_script (written in bash) reads from the file passed to it one line at a time and will detect:
- ❯ lines of code (syntax highlighting them as bash code)
- 💭 comments (syntax highlighting them as markdown)
- blank lines (preserving whitespace)
- 💬 and some other special lines
It uses meta-programming to build an augmented version of itself from each of these lines storing them in a temporary augmented_script file.
And finally it passes that file (and any other arguments specified on the command line) to asciinema run --command <augmented_script> for it to make a recording.
Nb. although the .asc scripts are used to produced asciinema recordings its expected that these files can also be run in bash/zsh
eg.
❯ source screencasts/demo-bash_functions.asc
a='a 0', b='b 0', c=''
-> f1(a='a 0', b='b 0', c='')
-> f1(a='a 0', b='b 0', c='')
BEFORE: a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 1', c='c 1')
AFTER : a='a 1', b='b 1', c='c 1'
BEFORE: a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 1', c='c 1')
AFTER : a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 2', c='c 2')
-> f1(a='a 1', b='b 0', c='c 2')
Sun Oct 17 20:56:56 AEDT 2021
-> f1(a='a 1', b='b 0', c='Sun Oct 17 20:56:56 AEDT 2021')
BEFORE: a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 3', c='c 3')
AFTER : a='a 0', b='b 0', c=''
-> f2(a='a 4', b='b 4', c='Sun Oct 17 20:56:56 AEDT 2021')
-> f2(a='a 4', b='b 4', c='Sun Oct 17 20:56:56 AEDT 2021')
-> f2(a='a 4', b='b 4', c='c 4')
Limitations
As the .asc is read in one line at a time, making it difficult (if not impossible) to execute multi-line commands in these shell scripts.
The two workarounds I could think of were:
- making every multi-line command fit on one line
- So this:
f1() { echo "-> f1(a='$a', b='$b', c='$c')" } - would have to be manually edited in the
.ascfile to this:f1() { echo "-> f1(a='$a', b='$b', c='$c')"; }
- inline the multi-line code from a
sourcecommand:
- So something like this:
source "${script%.asc}/f1.1" - could be used (eg. here) to source this file but be seemlessly displayed in the recording as:
f1() { echo "-> f1(a='$a', b='$b', c='$c')" }
Similar & Related Projects
- https://github.com/garbas/asciinema-scenario
Also included
asciinema-gh
This tool provides a command line playack menu of screencasts which it pulls from github repos.
It works with both public & private github repos.
(Nb. The recordings that appear in the menu don't necessarily have to be made using asciinema-rec_script,
but the menu will filter out all the .asc files from that directory.)
Requirements:
Example Usages:
asciinema-gh zechris/asciinema-rec_script- search for .cast files in https://github.com/zechris/asciinema-rec_script/tree/master/screencasts
REF=v0.9.0 asciinema-gh zechris/asciinema-rec_script- (which can be used with a github
REFs like release tags eg. v0.9.0)
- (which can be used with a github
REF=first_pr asciinema-gh zechris/asciinema-rec_script- (or branch names eg. first_pr)
asciinema-gh spectreconsole/spectre.console docs/input/assets/casts- (NB. a path can also be specified if the screencasts aren't found in the default
./screencasts)
- (NB. a path can also be specified if the screencasts aren't found in the default
echo 26 | screencast_dir=docs/input/assets/casts asciinema-gh spectreconsole/spectre.console- (to pre-select number
26from the menu)
- (to pre-select number