如何在不执行命令的情况下编辑当前的Shell命令?

时间:2020-01-16 14:19:35

标签: bash

关于如何使用“ edit-and-execute-command(Cx Ce)”使用编辑器来编辑和执行命令,似乎有很多信息,但是我想实现的是采用当前shell命令,应用某些过滤(使用脚本),然后将其返回以提示执行进一步的批准/手动更改。 bash有可能吗?

7 个答案:

答案 0 :(得分:8)

关于我的经历的最新消息

以下映射中的0"+y$dd部分确实是您应该仔细考虑的内容,并根据您的口味/工作流程/经验进行调整。

例如,我经常发现自己在缓冲区中多行结尾,而我只想执行光标所在的那一行;在这种情况下,我可以使用0"+y$dd:%d<CR>代替0"+y$dd

这只是可能的情况之一。

最喜欢vim的人的答案

原始答案

我经常需要做同样的事情,我这样做如下。 (我通常在set -o vi中使用bash,因此如果您使用默认的set -o emacs,则下面的点1和2是不同的;根据您的问题,它看起来像点1和2统一为 Ctrl + x ,然后是 Ctrl + e ,难于输入,恕我直言。)< / p>

  1. Escape 进入普通模式,
  2. 点击 v 进入编辑器以编辑命令,
  3. 根据需要编辑命令,

(这是您要提问的地方。)

  1. hit Escape 0 + y $ d d w q
    • 注意: 0 + y $ ,而不只是 + y y ,因为后者也会复制换行符,这将导致粘贴后执行命令在命令行中
  2. 将剪贴板粘贴在命令行上
      我猜怎么做取决于我所使用的终端;我在URxvt中按了 Ctrl + Alt + v
  3. 进行批准/手动编辑。

很显然,这只是一种解决方法,包括在删除整个命令之前将已编辑的命令复制到剪贴板,以便退出编辑器时不执行任何操作。但是这是我自己能得到的最好的。

更新

由于我的EDITOR(和VISUAL)等于vim,所以当我编辑命令时,我会在vim中对其进行编辑。

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

如果您使用vim作为编辑器,那么这为很多可能性提供了空间,因为您可以在.vimrc中定义一些映射以执行整个序列 Escape 0 + y $ d d w q 例如,在编辑命令行时很少使用的一条命令是 Leader d ;因此,您可以在map文件中放置以下.vimrc ping

au BufEnter /tmp/bash-fc.* nn <Leader>d 0"+y$dd:wq<CR>

因此上述配方中的第4步变为

  1. 命中 Escape Leader d

答案 1 :(得分:2)

在Bash / readline中不可能这样做,但是在zsh中是可能的 使用edit-command-line命令:

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

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

答案 2 :(得分:1)

现在我考虑一下,如果我们要坚持bash,也许@kenorb在注释中建议的变体是最好的解决方法(因为似乎没有解决方案)。

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

请注意,此策略仅增加了几次击键操作,因此效率会很高,具体取决于您的键入级别。

答案 3 :(得分:1)

我想向您介绍Bash的 Composure 框架(我不隶属于):https://github.com/erichs/composure

它提供了draftrevise的功能,听起来像它们可以帮助您解决您的问题。这是项目自述文件的(长)引号:

冷静可以帮助您快速起草简单的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函数,您可能想要制作它 通过重构和修订更好。使用revise ()命令 在您喜欢的编辑器中修改您的Shell函数。

  • 使用输入参数概括函数
  • 添加或删除功能
  • 添加用于文档的支持元数据

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

答案 4 :(得分:1)

这些片段可能使您更接近:

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

b)使用!#

从历史记录中获取当前行

使用所需的脚本替换日期。

c)手动编辑

d)如有必要,请以某种方式绑定!!:p,将新命令打印到命令行,但不执行该命令,从而使您可以手动对其进行编辑。

e)使用ctrl-J提交编辑的命令而不是换行符

否则他们可能不会....

答案 5 :(得分:1)

bash中有一个选项可以从历史记录中修改命令而不执行它。我不确定是否可以为此使用脚本,似乎不太可能。不过,您可以使用历史记录修饰符进行修改。

  1. 启用选项历史记录以防止执行修改后的命令
  2. 使用修饰符链来更改最后一个命令
  3. 使用“!”将结果放入命令行进行最终编辑

这是它的外观:

$ 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

答案 6 :(得分:0)

似乎至少不能通过键盘快捷键来实现:

$ 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