Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
ibar^ESC:q
/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".

#!/bin/bash
#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 ]
then
    find $OUTPUT_SH_FILE* -type f -exec echo -e \\n---------- '{}' \; -exec cat '{}'  \; 
    echo ^^^^^ script already exists ^^^^^
    exit 1
fi
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 "$@"
    do
        fullpath=`readlink -f "$f"`
        [ -e $OUTPUT_SH_FILE.in/"$fullpath" ] || cp --parents "$fullpath" $OUTPUT_SH_FILE.in 
    done
    /usr/bin/vim "$@"
    for f in "$@"
    do
        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
        )
    done
}
export PS1='[$OUTPUT_SH_FILE] \w>'
RCFILE_EOF
)

chmod +x $OUTPUT_SH_FILE
share|improve this question

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.

share|improve this answer
    
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.

share|improve this answer
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

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .