Question

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?

Was it helpful?

Solution 3

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( $_ )'
}

OTHER TIPS

This question has been asked here: use "!" to execute commands with same parameter in a script but in brief you need to

set -o history
set -o histexpand

in your script to enable history expansion.

History expansion seems to be expanded immediately, whereas other commands inside the body of a function are deferred until the function is called. Try defining the function at a shell prompt. I get bash: !-$CYCLE: event not found immediately, before the function definition is complete.

I tried escaping the exclamation point, but this causes it to be treated literally once the function is called, instead of being processed as a history expansion.

One alternative is a combination of eval and fc:

function cyc {
    CYCLE=3
    eval $( fc -nl -$CYCLE -$CYCLE )
}

I'll forgo the usual warning about eval because you'll simply be re-executing a command you previously ran, so caution will apply however you accomplish this. The given fc command will print a range of commands from history (-n suppresses the line number), and using the same value for the beginning and end of the range limits the output to a single command.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top