如何在不使用箭头键的情况下重复上一个命令?


113

我知道我可以Up用来遍历先前的命令。运行最后一个命令只需涉及Up+ Enter。但是,由于我在中花费了大量时间,因此我在考虑购买Happy Hacking Keyboardvim

该键盘没有箭头键,我知道如何获得这种行为的唯一方法是按Ctrl+ R并开始重复我以前的命令。

在没有箭头键的情况下,有没有一种简单的方法可以在UNIX终端中模拟Up+ Enter


1
您应该使用您使用的外壳替换终端标签。
Cristian Ciupitu 2014年

2
@照亮没有鼠标...
定量

2006年,Happy Hacking Keyboard键盘是否不再停产?
彼得·莫滕森

@PeterMortensen不,它仍然可用。您可能指的是第一个版本,但是较新的型号仍然可用。
定量

Answers:


163

随着csh或任何shell执行csh样的历史替换(tcshbashzsh):

!!

然后Enter


交替

!-1

然后Enter


Ctrl+ PEnter


魔术空间

另外,请注意,!!并且!-1在执行之前(可能为时已晚),并且不会为您自动展开。

如果使用bash,就可以把bind Space:magic-space进入~/.bashrc,然后按Space该命令后,将内嵌自动扩展它们,让您在执行之前对其进行检查。这对于前一段时间运行的命令的历史记录扩展特别有用,例如,!echo将拉出最后一个以开头的命令echo。借助魔术空间,您可以在命令运行之前对其进行预览。

这相当于bindkey ' ' magic-spacetcsh或中进行zsh


1
@Arman很高兴提供帮助。有很多历史扩展命令;该链接列出了其中一些。我已经编辑了一些有关魔术空间的信息,这些信息可能会有助于某些方法的使用。
Sparhawk

3
magic-space那是一个不错的选择!
fduff 2014年

1
还有一个histverify选项,shopt该选项将导致readline进行历史记录扩展,但在首次按下Enter键时不执行命令。这将使您评估结果并决定是否要运行该结果。
伊坦·赖斯纳

2
从来不明白为什么!比CTRL-P使用得多。CTRL-P使您可以在执行命令之前先查看该命令-甚至可以对其进行修改。我总是觉得自己正在用!!掷骰子。
2014年

1
@abonet我刚刚找到的另一个用途!!是使用in-place扩展。例如sudo !!
Sparhawk

48

大多数具有命令行编辑功能的外壳程序都支持Emacs按键绑定。(一小部分)

Up     Ctrl+P
Down   Ctrl+N
Left   Ctrl+B
Right  Ctrl+F
Home   Ctrl+A
End    Ctrl+E
Delete Ctrl+D

另外,您可以通过添加set -o vi到Shell启动文件(例如,~/.bashrc)来将Shell 设置为使用vi命令编辑模式。然后,例如,您可以

  • 使用EsckEnter 重新执行前一个命令(同!!)。减号键-也可以用作“上移”命令。
  • 使用EsckkkkkkkkkkkkEnterEsc12kEnter 重新执行前面的第12条命令(与相同!-12)。
  • 使用Esc和运动命令(即,k适当重复),然后编辑在那里找到的bash命令行。记住,你将仍处于vi命令模式,所以你需要使用vi编辑命令(例如IACR,或相应的小写字母之一)实际上从历史添加到命令。
    因此,例如,EsckisudoSpaceEnter等价于sudo !!
  • 对于高级用户:你甚至可以复制(Ÿ ANK)从一条线和粘贴(文字p UT)它在另一个,这样你就可以做到效果媲美!-2:- !$。(不幸的是,它似乎不支持命名缓冲区。)

我知道与终端的emacs关系...但是vi窍门很棒!!!
Dox

我得到了delete在岩组CTL + U
蒂莫

1
这是由readline库实现的。其他快捷方式可以在其文档中找到。
Spidey

28

我最喜欢的是CTRL+ P然后CTRL+O

默认情况下,这有效,不需要额外的配置。^ P将使您切换到最后一个命令,而^ O将使您执行当前行

请注意,CTRL+ O可以根据需要多次使用


2
^ O在我的Mac上不执行任何操作。
Snowcrash

1
@Snowcrash Try^J
雏菊

即使我已经做了一个lspwd以前的操作,也只是回显一个空白行。
Snowcrash

@Snowcrash是^ P然后是^ J ...
雏菊

Ctrl + P在HP-UX上不起作用(我不知道它使用的是哪个Shell)。解决方法是调用“ zsh”。
彼得·莫滕森

14

当然!既然您习惯了vi键盘绑定,为什么不配置您的外壳来响应它们呢?为此bash,请将其放入您的~/.inputrc

set editing-mode vi

正在运行的bash实例将不会重新读取文件,因此请注销并重新登录。

zsh甚至会发现这个要求:如果没有你的启动脚本迫使编辑模式下使用的一种方式或其他bindkey ,如果你的$EDITOR检测环境变量包含vi,那么它会自动启用vi键绑定。如果您需要强制执行此操作,请将其放入您的~/.zshrc

bindkey -v

此后,使用ESC照常进入命令行和kj向向上和向下移动。

:大多数外壳程序中的默认外壳程序绑定是emacs绑定,因此实际上Crtl-P并且Ctrl-N应该已经可以工作而无需更改任何内容。


9

随着实施任何POSIX外壳用户可携性选项(包括kshzshbashyash),你也可以使用fc命令:

fc -e : -1

看一个例子:

$ echo "hello"
hello

$ fc -e : -1
echo "hello"
hello

乔纳森·莱弗勒(Jonathan Leffler)的历史记录回答中的更多信息,请参阅执行一系列命令


6

对于所有Mac iterm2用户:

您可以将+ 绑定R0x0C 0x10 0x0d。这将清除终端并运行最后一条命令。

iterm 2的关键偏好


有什么方法可以在不清除终端的情况下重复上一条命令吗?
卢克·戴维斯

啊,没关系:对于任何阅读此内容的人,请在不清除终端的情况下重复使用0x10 0x0d,即使用(即省略0x0C)。
卢克·戴维斯


3

ksh外壳具有默认别名r,该别名重复最近的命令。它必须绑定到fc -s

alias r='fc -s'

有趣的是,内置bash文档fchelp fc,以及手册本身)甚至提到了这一点,但它不是该shell中的默认别名:

与此配合使用的有用别名是r='fc -s',这样,键入r cc 将以最后一个命令开始运行最后一个命令cc,键入将r重新执行最后一个命令。

在中bash,即使您已使用关闭了历史记录扩展,这也将起作用set +H

zsh外壳程序中,有一个r内建文件,据证明与相同fc -e -

fc实用程序是POSIX标准实用程序


2

随着csh或实施任何壳csh般的历史替换(tcshbashzsh),你也可以使用!<beginning of command>打电话的最后一个命令开头<beginning of command>

例如,如果您跑步

$ tail file.txt
$ less otherfile.txt
$ !ta

!ta 将执行 tail file.txt


1

tl; dr !!仅将最后一个命令附加到当前命令之后。<backtick>!!<backtick> 执行最后一个命令,并将输出附加到当前命令。

实际上有2个变体:

  1. 最后一个命令本身
  2. 最后一条命令的结果

让我向您展示2个示例:

例子1

$ mkdir /test
mkdir: /test: Permission denied

$ sudo !!
sudo mkdir /test
Password:

如您在上面看到的,我正在执行一个命令,实际上只是在追加最后一个命令。

另一种变化

例子2

$ find ~/Documents "test.txt"
/Users/<user>/Documents/test.txt

$ vi `!!`
# Opens test.txt. But if you do
$ vi !!
vi find ~/Documents -name "test.txt"
VIM - Vi IMproved 8.1 (2018 May 18, compiled Oct 29 2018 06:55:58)
Unknown option argument: "-name"
More info with: "vim -h"

为+1 vi `!!`。非常有用
le_daim

0

当我使用良好的xterm模拟器(例如,腻子)时,我最喜欢的处理方法是选择包括换行符的命令,将其复制到剪贴板,然后右键单击鼠标将其粘贴。单击即可重复该命令。这对于用分号分隔的命令序列也可以正常工作。


0

您可以!n在终端中执行第n条命令。其中“ n”是history命令的行号。


哪个外壳扩展!?到最后一个命令?您确定您没有将其混淆!!(其他答案已对此进行了说明)?
Anthony Geoghegan

抱歉,实际上我当时正在尝试此命令。请检查编辑后的答案。@AnthonyGeoghegan
拉维·塞夫塔

这是我一直在寻找的捷径。谢谢!
le_daim

0
  • 键入历史记录,并记下要执行和使用的命令前面的数字 !number

  • 您还可以使用!-1(1是您执行的最后一个命令,将其替换为从下面执行该操作时获得的计数,将最后一个执行为1)

  • !-2(倒数第二,依此类推)
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.