Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

3 Answers 3

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 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 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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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