如何编写一个 bash 别名,用前一个命令的最后一个词替换 !$?

如何编写一个 bash 别名,用前一个命令的最后一个词替换 !$?

我有一个名为 的脚本cpodin,它将几个构建工件复制到另一个目录。之后,我SHA1SUM在目标目录中进行编辑。

例如:

cpodin /foo/bar/baz
vim !$/SHA1SUM

如何使后一个命令成为别名fixsha,该别名不带任何参数,并SHA1SUM在前一个命令的最后一个参数指定的目录中进行编辑?

alias fixsha='vim !$/SHA1SUM'

导致尝试编辑!$/SHA1SUM而不是/foo/bar/baz/SHA1SUM

答案1

Bash 在别名扩展后不执行历史扩展,因此你必须使用 明确执行此操作history,详情记录在Bash 历史内置函数并摘录如下。

history -ps args

  • -p
    执行历史替换参数并将结果显示在标准输出上,而不将结果存储在历史列表中。
  • -s
    参数作为单个条目添加到历史列表的末尾。

的别名alias fixsha='vim $(history -p !$)/SHA1SUM'在大多数情况下都有效,但在!$扩展到包含空格的路径时则无法达到预期效果。在路径参数周围添加双引号将保护空格上的任何转义,并导致vim "/foo/bar\ baz/SHA1SUM"而不是所需的vim /foo/bar\ baz/SHA1SUM或其等效项vim "/foo/bar baz/SHA1SUM"

所以除了显式的历史扩展之外,eval还需要解开一层引用。

alias fixsha='eval vim "$(history -p !$)/SHA1SUM"'

笔记:您可能会惊讶地发现,上述别名定义中的双引号是不必要的。这是因为扩展值!$和之间没有空格/SHA1SUM来触发 bash 的分词。但是,我喜欢它们的存在,以强调它正在扩展为单个参数的意图。

相关内容