Skip to content

Instantly share code, notes, and snippets.

@mjf
Last active May 3, 2018 13:03
Show Gist options
  • Save mjf/1353111 to your computer and use it in GitHub Desktop.
Save mjf/1353111 to your computer and use it in GitHub Desktop.
Record and replay shell sessions using script(1) and scriptreplay(1)
#! /bin/sh
# Record - record shell session using script(1)
# Copyright (C) 2011 Matous J. Fialka, <http://mjf.cz/>
# Released under the terms of The MIT License
RECORD_PATH="$HOME/.typescripts/%Y/%m/%d"
RECORD_FILE='%H%M%S'
RECORD_TIMING_FILE="$RECORD_FILE.timing"
if ! RECORD_PATH=`
date "+$RECORD_PATH" 2>/dev/null
`
then
echo 'Error: invalid typescript path specified.' 1>&2
exit 1
fi
if ! mkdir -p "$RECORD_PATH" 2>/dev/null
then
echo "Error: could not create typescript path $RECORD_PATH." 1>&2
exit 1
fi
if ! RECORD_FILE=`
date "+$RECORD_FILE" 2>/dev/null
`
then
echo 'Error: invalid typescript file specified.' 1>&2
exit 1
fi
if [ -f "$RECORD_FILE" ]
then
echo "Error: typescript file $RECORD_FILE exists." 1>&2
exit 1
fi
if ! RECORD_TIMING_FILE=`
date "+$RECORD_TIMING_FILE" 2>/dev/null
`
then
echo Error: invalid typescript timing file specified. 1>&2
exit 1
fi
if [ -f "$RECORD_TIMING_FILE" ]
then
echo "Error: typescript timing file $RECORD_TIMING_FILE exists." 1>&2
exit 1
fi
RECORD_FILE="$RECORD_PATH/$RECORD_FILE"
RECORD_TIMING_FILE="$RECORD_PATH/$RECORD_TIMING_FILE"
if ! script -c "$*" -t "$RECORD_FILE" 2>"$RECORD_TIMING_FILE"
then
echo "Error: could not record data." 1>&2
rm -f "$RECORD_FILE"
rm -f "$RECORD_TIMING_FILE"
exit 1
fi
#! /bin/sh
# Replay - replay typescript using scriptreplay(1)
# Copyright (C) 2011 Matous J. Fialka, <http://mjf.cz/>
# Released under the terms of The MIT License
if [ $# -eq 0 ]
then
echo "Usage: replay TYPESCRIPT [-c] [DIVISOR]" 1>&2
exit 1
fi
RECORD_FILE="$1"
RECORD_TIMING_FILE="$RECORD_FILE.timing"
shift
if [ "$1" = '-c' ]
then
shift
if ! TEMPORARY_FILE=`mktemp 2>/dev/null`
then
echo "Error: could not create temporary file." 1>&2
exit 1
fi
if ! awk '
{ printf "%f %d\n", (($1 - last) > 1) ? 1 : $1, $2 }
' "$RECORD_TIMING_FILE" >"$TEMPORARY_FILE" 2>/dev/null
then
echo "Error: could not condense data, sorry." 1>&2
rm -f "$TEMPORARY_FILE"
exit 1
fi
RECORD_TIMING_FILE="$TEMPORARY_FILE"
fi
if ! [ -f "$RECORD_FILE" ]
then
echo "Error: typescript file $RECORD_FILE not found." 1>&2
exit 1
fi
if ! [ -f "$RECORD_TIMING_FILE" ]
then
echo "Error: typescript timing file not found." 1>&2
exit 1
fi
if ! scriptreplay "$RECORD_TIMING_FILE" "$RECORD_FILE" $1 2>/dev/null
then
echo "Error: could not replay data." 1>&2
exit 1
else
echo
fi
rm -f "$TEMPORARY_FILE"
@mjf
Copy link
Author

mjf commented Nov 9, 2011

I have to record/replay my terminal sessions sometimes. I used to use script(1) to record and scriptreplay(1) to replay the sessions but the use of the tools was quite painful. Thus I managed to write these two simple wrappers to make the job much easier. The usage is as simple as follows:

$ record.sh /bin/sh
Script started, file is /home/mjf/.typescripts/2011/11/09/223353
...
Script done, file is /home/mjf/.typescripts/2011/11/09/223353

Now I can very simply replay the recorded data:

$ replay /home/mjf/.typescripts/2011/11/09/223353
...

Easy enough now. I also added -c option to the replay script which means "condense data". Any pause longer than one second is condensed to exactly one second. You know that - doing some work and your phone is ringing... uff. There is no simple way to rewind while using the scriptreplay(1) so I managed to simply squeeze the timing data in such cases. It works as charm.

$ replay /home/mjf/.typescripts/2011/11/09/223353 -c
...

You can also speed up the replay the same way as you did in case you used the scripreplay(1) tool itself.
Just add divisor as the second (or in case of -c the third) argument.

$ replay /home/mjf/.typescripts/2011/11/09/223353 10
...

Recording terminal sessions not only is helpful for your reference or as a memo but you can easily build very comprehensive tutorials using the method.

Keep it simple! I hope it helps. Enjoy!

@mjf
Copy link
Author

mjf commented Aug 31, 2015

Useful alias:

replaylast='replay `ls -1 /home/mjf/.typescripts/*/*/*/* |tail -3 |head -1`'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment