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


13

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


这不是问题的正确答案,而是尝试使用ZSH终端而不是本机Bash。它具有自动补全功能,因此不要立即执行命令。我已经亲自尝试过这种特定情况,并且总是需要在执行操作时按Enter键edit-and-execute-command
Praveen Premaratne

1
对我有用的快捷方式是Escape+ V,但仍将执行命令。因此,对于变通办法,我将echo在前面添加以通过将命令打印到控制台进行检查来执行它。
kenorb

2
你能举一个具体的例子吗?我不理解“应用某些过滤(使用脚本),然后将其返回给提示符”。
肯特

3
@PraveenPremaratne:zsh不是终端,而是shell
Arkadiusz Drabczyk

Answers:


7

我的经验的最新更新

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

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

这只是可能的情况之一。

对那些喜欢的人的最终答案 vim

原始答案

我经常需要做同样的事情,我做如下。(我通常使用set -o viin bash,因此如果使用set -o emacs默认值,则下面的点1和2是不同的;根据您的问题,看起来点1和2在Ctrl+ x后面是统一的,后面是Ctrl+ e,这很难键入,恕我直言)

  1. Escape是在正常模式下,
  2. 点击v进入编辑器以编辑命令,
  3. 根据需要编辑命令,

(这是您提出问题的地方。)

  1. Escape0"+y$dd:wq
    • 注意:0"+y$,不是简单的"+yy,因为后者也会复制换行符,这将导致在将命令粘贴到命令行后执行命令,
  2. 将剪贴板粘贴在命令行上
    • 我想如何做到这一点取决于您使用的终端。我打Ctrl+ Alt+ vURxvt
  3. 进行批准/手动编辑。

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

更新资料

由于我的EDITOR(和VISUAL)等于vim,因此当我编辑命令时,我在中进行了编辑vim

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

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

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

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

  1. 击中 EscapeLeaderd

对我来说,这是编辑命令的最佳方法
A.Villegas

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打开你的编辑器,编辑行,离开编辑器-你会看到更新的命令行,但它不会自动执行。


1

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

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

请注意,此策略仅添加了几次击键,因此根据键入级别的不同,它可能会非常有效。


1

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

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

b)使用以下命令从历史记录中获取当前行 !#

用您想要的任何脚本替换日期。

c)手动编辑

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

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

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


1

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

  1. 启用选项histverify以防止执行修改后的命令
  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

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

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.