linuxbashconvenience-methods

Why doesn't bash history expansion work in functions?


When I'm programming, I'll find myself cycling through the same three shell commands, e.g:

  1. vim myGraphic.cpp
  2. g++ -lglut -lGLU myGraphic.cpp -o prettyPicture
  3. ./prettyPicture

In order to avoid hitting the uparrow key thrice every time, I put the following in my bashrc:

function cyc { 
    CYCLE=3
    !-$CYCLE 
}

When I use the 'cyc' function, however, I get the error

"bash: !-3: command not found".

This technique of history expansion works interactively with the shell, but it does not seem to work with function definitions. What is the explanation for this difference? How might I make a function equivalent to 'cyc' that works?


Solution

  • One way. It extract last four lines of your history, taking into account that history will be included, from that extract the first one for same result that !-3 and use perl to remove either the history number and leading spaces before executing the instruction.

    function cyc {
        CYCLE=4
        history | tail -"$CYCLE" | head -1 | perl -ne 's/\A\s*\d+\s*// && system( $_ )'
    }