为什么不在功能中抨击历史扩展工作?

时间:2013-06-08 15:07:43

标签: linux bash convenience-methods

当我编程时,我会发现自己循环使用相同的三个shell命令,例如:

  1. vim myGraphic.cpp
  2. g++ -lglut -lGLU myGraphic.cpp -o prettyPicture
  3. ./prettyPicture
  4. 为了避免每次都击中uparrow键三次,我将以下内容放入我的bashrc中:

    function cyc { 
        CYCLE=3
        !-$CYCLE 
    }
    

    但是,当我使用'cyc'功能时,我收到错误

      

    “bash:!-3:找不到命令”。

    这种历史扩展技术与shell交互工作,但它似乎不适用于函数定义。这种差异的解释是什么?我怎样才能创建一个等效于'cyc'的函数?

3 个答案:

答案 0 :(得分:1)

此问题已在此处提出:use "!" to execute commands with same parameter in a script但您需要

set -o history
set -o histexpand
在脚本中

启用历史记录扩展。

答案 1 :(得分:1)

历史扩展似乎会立即扩展,而函数体内的其他命令将被推迟,直到调用该函数。尝试在shell提示符下定义函数。在函数定义完成之前,我立即得到bash: !-$CYCLE: event not found

我尝试转义感叹号,但这会导致在调用函数后对其进行字面处理,而不是作为历史扩展处理。

另一种选择是evalfc

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

我会放弃关于eval的通常警告,因为你只是重新执行你之前运行的命令,所以不管你做到了什么都要谨慎。给定的fc命令将从历史记录中打印一系列命令(-n抑制行号),并且使用相同的值开始和结束范围将输出限制为单个命令。 / p>

答案 2 :(得分:0)

一种方式。它提取了历史记录的最后四行,考虑到将包含history,从该摘录中提取第一行!-3并使用perl删除历史记录编号在执行指令之前引导空格。

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