Is there a tool to record an interactive shell session to a shell script?

For example if we entered in a terminal:

interactive2sh reconfig_foo
vim /etc/foo.cfg
/etc/init.d/foo restart

then I'd want the tool to create a shell script containing something like:

echo bar >> /etc/foo.cfg
/etc/init.d/foo restart

I can record an interactive session into a shell script using the code below. However, I would have thought that this was a common enough task that there would be an existing tool. Whenever I search for such a tool I just get lots of references to script/scriptreplay which would reproduce the output but wouldn't actually reconfigure the service "foo".

#prototype of interactive2sh, a tool for recording a bash session into a shell script 
export OUTPUT_SH_FILE=~/$1.auto.sh
if [ -e $OUTPUT_SH_FILE ]
    find $OUTPUT_SH_FILE* -type f -exec echo -e \\n---------- '{}' \; -exec cat '{}'  \; 
    echo ^^^^^ script already exists ^^^^^
    exit 1
mkdir $OUTPUT_SH_FILE.in
mkdir $OUTPUT_SH_FILE.out
echo 'SH_FILE=`readlink -f "$0"`' >> $OUTPUT_SH_FILE
echo cd `pwd` >> $OUTPUT_SH_FILE

#Start a new shell, which logs various things needed to replay the commands
bash --rcfile <(
cat << "RCFILE_EOF"
set +x
source "$HOME/.bashrc"
export PROMPT_COMMAND='RETRN_VAL=$?;echo "$(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//" ) # [$$] [RETRN_VAL=$?]" >> $OUTPUT_SH_FILE'
vim () {
    for f in "$@"
        fullpath=`readlink -f "$f"`
        [ -e $OUTPUT_SH_FILE.in/"$fullpath" ] || cp --parents "$fullpath" $OUTPUT_SH_FILE.in 
    /usr/bin/vim "$@"
    for f in "$@"
        fullpath=`readlink -f "$f"`
        test ! -e $fullpath || cmp "$fullpath" $OUTPUT_SH_FILE.in/"$fullpath" || (
            cp --parents "$fullpath" $OUTPUT_SH_FILE.out
            echo mv $fullpath $fullpath.`date -r $fullpath +%F`.bak >> $OUTPUT_SH_FILE
            echo cp '$SH_FILE'.out/$fullpath $fullpath >> $OUTPUT_SH_FILE
export PS1='[$OUTPUT_SH_FILE] \w>'

chmod +x $OUTPUT_SH_FILE

I've hacked together a very basic implementation which might be enough for your needs. It's based on two scripts: record and replay.

Here is the record script:

history | tail -1 | awk '{ print 1+$1 }' > /tmp/record

And this is the replay script:

fc -l `cat /tmp/record` `history | tail -1 | awk '{ print $1-1 }'` | cut -d\  -f2-

The first one saves your current history number into /tmp/record. The second script shows all the commands you have given since record was invoked.

  • Thanks, I'd prefer to store whether the command succeeded for failed though. That information could be useful for cleaning up the script later.
    – gmatht
    Mar 12 '14 at 8:57

Have you tried script? It can be used to do just that.

  • 1
    I have tried script. What tool would you use to convert typescript to a shell script that could be executed on another machine?
    – gmatht
    Feb 23 '14 at 14:53

There don't seem to be any existing tools for recording interactive sessions to shell scripts. However, I've written a quick shell script that seems to work well enough if you are only using text editors and non-iterative commands. It is availiable at: https://github.com/gmatht/joshell/blob/master/interactive2sh

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.