【问题标题】:Converting a history command into a shell script将历史命令转换为 shell 脚本
【发布时间】:2013-03-30 09:13:09
【问题描述】:

这是我认为很多人会经常使用的东西之一,但我似乎找不到任何人写过关于这类东西的文章。

我发现很多时候我在命令行单行程序上进行了很多迭代,当我最终经常使用它,或者预计将来想要使用它,或者当它变得很麻烦时在一行中使用,通常最好将单行转换为 shell 脚本并将其粘贴在合理且易于访问的位置,例如 ~/bin

使用任何涉及文本编辑器的迂回方法来完成这项工作显然太麻烦了,而且可以简单地在 shell 上完成,例如在 zsh 输入中

echo "#!/usr/bin/env sh" > ~/bin/command_from_history_number_523.sh && echo !523 >> ~/bin/command_from_history_number_523.sh

然后按 Tab 注入!523rd 命令,并以某种方式将其硬塞到一个可以保存的字符串中。

这特别麻烦,至少有三个问题:

  • 在 bash 中不起作用,因为它没有完成 !523
  • 需要一些人工检查和弦擒纵机构
  • 需要输入太多诸如脚本名称必须输入两次

看来我需要在这里编写一些元 shell 脚本。

我认为一个好的解决方案可以在 bash 和 zsh 下运行,它可能应该通过使用两个参数来工作,一个整数作为历史命令编号,一个用于在硬编码目录中弹出的 shell 脚本名称,其中包含一个命令。此外,在 bash 下,多行命令似乎被视为单独的命令,但我愿意假设我们在这里只关心单行命令,并且此时我只使用 zsh。

这里的绊脚石是我认为即使在使用 zsh 时我仍然会通过 bash 运行 shell 脚本,因此它不太可能能够解析 zsh 的历史文件。我可能需要把它做成两个单独的程序。

更新:我同意@Floris 的评论,即直接使用 !!尽管我不确定如何进行这项工作,但会有所帮助。假设我的用法是

mkscript command_number_24 !24

这是不够的,因为mkscript 将接收第 24 条命令的扩展内容。如果第 24 条命令包含任何文件 glob 或类似文件,它们将已经被扩展。这很糟糕,我基本上想要历史文件的内容,即原始命令字符串。我想这可以通过在此处手动实现这些快捷方式来解决。或者干脆把它搞砸,只取一个整数参数。

【问题讨论】:

  • 我不同意“使用……文本编辑器显然太麻烦”的前提。当脚本片段需要变得可重用时,我需要修改它以便处理参数等。这通常意味着改进错误处理。这些是我在文本编辑器中最擅长的事情。我使用“历史编辑”机制(bash 启动 vim 中的 vi 模式)再次编辑脚本,将其保存到 ~/bin 中的文件,然后从缓冲区中删除并保存它(所以它是不再执行)。然后我可以修复脚本;添加标识它的作用等的前导注释。
  • 只是为了确保您的问题很清楚:您想要一个用makescript somename !123 调用的脚本(我们称之为mkscript),它为编号为123 的命令创建一个“包装器”在你的历史中。我建议可以包含!,这样您就可以在最后一个命令中键入!!,而不必找出历史编号。您可以测试第二个参数是单个整数还是字符串,以确认使用的语法。这就是你心中的那种东西吗?不过,我必须同意@JonathanLeffler 的观察......
  • @JonathanLeffler 你的观点是正确的,但是我这样做也是完全合理的然后使用已经为我创建的shell脚本shebang进入文本编辑器,等弗洛里斯,是的。
  • 我应该说“要求使用文本编辑器可能有点矫枉过正”。除了我们中最懒的人之外,这可能不是“显然太麻烦”了。我无休止地努力渴望变得最大限度地懒惰。

标签: bash shell unix zsh


【解决方案1】:
function mkscript() { 
    echo '#!/bin/bash' > ~/bin/$2
    history -p '!'$1 >> ~/bin/$2
}

仅在 Bash 中测试。

来自 OP 的更新:在 zsh 中,我可以使用 fc -l $2 $2 完成此操作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 2018-07-29
    • 2012-01-25
    • 2013-12-25
    • 2011-09-04
    • 2015-12-30
    相关资源
    最近更新 更多