Bash 如何编辑当前的shell命令而不执行它?

Bash 如何编辑当前的shell命令而不执行它?,bash,Bash,关于如何使用编辑器使用“edit and execute command(C-x C-e)”编辑和执行命令,似乎有很多信息,但我想实现的是使用当前的shell命令,应用某些筛选(使用脚本),然后在执行之前返回它以提示进一步批准/手动更改。bash可以这样做吗?键盘快捷键似乎不可能这样做,至少: $ bind -P | grep -e command -e edit complete-command can be found on "\e!". edit-and-execute-command c

关于如何使用编辑器使用“edit and execute command(C-x C-e)”编辑和执行命令,似乎有很多信息,但我想实现的是使用当前的shell命令,应用某些筛选(使用脚本),然后在执行之前返回它以提示进一步批准/手动更改。bash可以这样做吗?

键盘快捷键似乎不可能这样做,至少:

$ bind -P | grep -e command -e edit
complete-command can be found on "\e!".
edit-and-execute-command can be found on "\C-x\C-e".
emacs-editing-mode is not bound to any keys
possible-command-completions can be found on "\C-x!".
vi-editing-mode is not bound to any keys
根据我的经验最新更新 以下映射中的部分
0”+y$dd
确实值得您仔细考虑,并根据您的喜好/工作流程/体验进行调整

例如,我经常发现自己在缓冲区中有多行,我只想执行光标所在的行;在这种情况下,我可以使用
0“+y$dd:%d
而不是
0”+y$dd

这只是其中一种可能的情况

对于喜欢
vim
  • vim
    设置为您的
    EDITOR
    /
    VISUAL
    ,以便在编辑命令行时,您将使用
    vim
    对其进行编辑
  • au BufEnter/tmp/bash fc.*nn d 0“+y$dd:wq
    放在
    ~/.vimrc
    文件中,以将Leaderd(编辑命令时很少使用)映射到操作“删除当前行到
    +
    寄存器中,而不带尾随下线”。
  • vim
    编辑器中编辑完命令后,点击EscapeLeaderd
  • 将剪贴板粘贴到终端(这取决于终端)
原始答案 我经常需要做同样的事情,我做的如下。(我通常在
bash
中使用
set-o vi
,因此,如果使用
set-o emacs
,则下面的第1点和第2点是不同的,这是默认设置;根据您的问题,看起来第1点和第2点是统一的,在Ctrl+x之后是Ctrl+e,这更难键入,imho。)

  • 点击Escape以进入正常模式
  • 点击v进入编辑器编辑命令
  • 按我喜欢的方式编辑命令
  • (这就是你要问的问题。)

  • 命中逃逸0“+y$dd:wq,
    • 注意:0“+y$,而不是简单的“+yy”,因为后者也会复制换行符,这将导致在命令行中粘贴命令时执行命令
  • 将剪贴板粘贴到命令行上
    • 我想这取决于您使用的终端;我在
      URxvt
      中按了Ctrl+Alt+v
  • 转至批准/手动编辑
  • 显然,这只是一种解决方法,包括在删除整个命令之前将已编辑的命令复制到剪贴板中,以便在退出编辑器时不会执行任何操作;不过,这是我能为自己获得的最好结果

    更新 由于我的
    EDITOR
    (和
    VISUAL
    )等于
    vim
    ,因此当我编辑命令时,我在
    vim
    中编辑它

    在这方面,我注意到缓冲区名为
    /tmp/bash fc.random
    ,其中
    random
    是一个6个字符的字母数字随机字符串

    如果您使用
    vim
    作为编辑器,这将为许多可能性提供空间,因为您可以在
    .vimrc
    中定义一些映射来执行整个序列Escape0“+y$dd:wq。例如,编辑命令行时很少使用的一个命令是Leaderd;因此,您可以将以下
    map
    ping放入
    .vimrc
    文件中

    au BufEnter /tmp/bash-fc.* nn <Leader>d 0"+y$dd:wq<CR>
    
    au BufEnter/tmp/bash fc.*nn d 0“+y$dd:wq
    
    因此,上述配方中的步骤4变为

  • 击中逃逸者

  • 在Bash/readline中不可能做到这一点,但在zsh中是可能的 使用
    编辑命令行
    命令:

    darkstar% autoload edit-command-line; zle -N edit-command-line
    darkstar% bindkey "^X^E" edit-command-line
    

    现在按Control-x Control-e打开编辑器,编辑行,离开编辑器-您将看到更新的命令行,但它不会自动执行。

    现在我想了想,也许@kenorb在注释中建议的变体是最好的解决方法(因为似乎不存在解决方案),如果我们想坚持使用
    bash

    您可以做的是在命令前面加上一个
    (bash中的注释字符),而不是
    echo
    。然后退出exitor时,命令将无效,您只需按向上箭头键(或k,如果使用
    set-o vi
    ),删除
    ,然后确认


    请注意,此策略只添加了几个击键,因此根据您的键入级别,它可以相当有效。

    我想向您介绍Bash的Composure框架(我与它无关):

    它提供了
    草稿
    修订
    功能,听起来它们可以帮助您完成所要做的事情。以下是项目自述文件中的一段(长)引用:

    通过让您快速起草简单的shell函数, 将长管道过滤器和复杂命令分解为 可读和可重用的块

    先起草,后提问 一旦你制作了一个命令的宝石,不要扔掉它
    draft()
    并给它起个好名字。这会将上一个命令存储为 以后可以重用的函数。把它想象成一个草稿

      $ cat servers.txt
      bashful: up
      doc: down
    
      up-arrow
    
      $ cat servers.txt | grep down
      doc: down
    
      $ draft finddown
    
      $ finddown | mail -s "down server(s)" admin@here.com
    
    修改,修改,修改! 现在您已经有了一个最小的shell函数,您可能想要使它 通过重构和修订,效果更好。使用
    revision()
    命令 在您喜爱的编辑器中修改shell函数

    • 用输入参数推广函数
    • 添加或删除功能
    • 为文档添加支持元数据

      $ revise finddown
      finddown ()
      {
        about finds servers marked 'down' in text file
        group admin
        cat $1 | grep down
      }
      
      $ finddown servers.txt
      doc: down
      

    这些片段可能会让你更接近:

    a) 替换换行符换行符的常规绑定(ctrl-M)
    bind-x'\C-M:date“

    b) 使用$ shopt -s histverify $ ls *.sh script1.sh script2.sh script3.sh script-return.sh $ !!:s/*/script1/:p ls script1.sh $ !!:s/1/2/:p ls script2.sh $ !! $ ls script2.sh script2.sh