158

I know I can use Up to iterate through previous commands. Running the last command simply involves Up + Enter. However, I was thinking of buying the Happy Hacking Keyboard as I spend a lot of time in vim.

This keyboard has no arrow keys, and the only way I know how to get this kind of behaviour is by pressing Ctrl + R and beginning to repeat my previous command.

Is there an easy way to emulate Up + Enter in an UNIX terminal without the arrow keys?

4
  • 1
    You should replace the terminal tag with the shell that you use. Commented Jul 31, 2014 at 7:40
  • 2
    @illuminÉ no mouse...
    – quant
    Commented Aug 2, 2014 at 0:15
  • Wasn't Happy Hacking Keyboard discontinued in 2006? Commented Aug 19, 2018 at 17:41
  • @PeterMortensen no it's still available. You might be referring to the first version, but the newer models continue to be available.
    – quant
    Commented Aug 19, 2018 at 17:55

16 Answers 16

218

With csh or any shell implementing csh-like history substitution (tcsh, bash, zsh):

!!

Then Enter.


Or alternatively:

!-1

Then Enter.


Or Ctrl+P, Enter


Magic space

Also, note that !! and !-1 will not auto-expand for you, until you execute them (when it might be too late).

If using bash, you can put bind Space:magic-space into ~/.bashrc, then pressing Space after the command will auto-expand them inline, allowing you to inspect them before execution. This is particularly useful for history expansion from a command run a while ago, e.g. !echo will pull the last command run starting with echo. With magic space, you get to preview the command before it's run.

That's the equivalent of doing bindkey ' ' magic-space in tcsh or zsh.

14
  • 1
    @Arman Glad to help. There's a whole lot of history expansion commands; the link lists some of them. I've edited in some information about magic space that might help with usage of some of these.
    – Sparhawk
    Commented Jul 31, 2014 at 4:01
  • 5
    magic-space that is one sweet option!
    – fduff
    Commented Jul 31, 2014 at 7:10
  • 3
    There's also the histverify option to shopt which will cause readline to perform the history expansion but not execute the command on the first press of the enter key. Which will let you evaluate the result and decide if that's what you want to run. Commented Jul 31, 2014 at 13:33
  • 2
    Never understood why !! is used so much more than CTRL-P. CTRL-P lets you see the command before executing it -- and you can even make modifications to it. I always feel like I'm rolling the dice with !!.
    – abonet
    Commented Aug 5, 2014 at 21:30
  • 2
    @abonet Another use that I just found for !! is using its expansion in-place. For example sudo !!.
    – Sparhawk
    Commented Aug 7, 2014 at 2:40
75

Most shells that have a command line editing feature support Emacs key bindings. (a tiny subset)

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

Alternatively, you could set up your shell to use vi command editing mode, by adding set -o vi to your shell startup file (e.g., ~/.bashrc).  Then, for example, you can

  • Use EsckEnter to re-execute the previous command (same as !!).  The minus key - also works as a "move up" command.
  • Use EsckkkkkkkkkkkkEnter or Esc12kEnter to re-execute the 12th previous command (same as !-12).
  • Use Esc and a motion command (i.e., k, suitably repeated), and then edit the bash command line you find there.  Remember, you will still be in vi command mode, so you will need to use a vi editing command (e.g., I, A, C, R, or one of their lowercase counterparts) to actually add to the command from history.
    So, for example, EsckisudoSpaceEnter is equivalent to sudo !!.
  • For advanced users: you can even copy (yank) text from one line and paste (put) it on another, so you can accomplish results comparable to !-2:- !$.  (Unfortunately, it does not seem to support named buffers.)
5
  • I knew about the emacs relation with the terminal... but the vi trick was great!!!
    – Dox
    Commented Aug 6, 2014 at 20:06
  • I got for delete Ctl+u in Zsh
    – Timo
    Commented Jan 11, 2018 at 21:08
  • 1
    This is implemented by the readline library. Further shortcuts may be found on its documentation.
    – Spidey
    Commented Feb 18, 2018 at 18:38
  • 1
    This is the answer I was looking for! Commented Dec 29, 2020 at 20:10
  • I have waited my whole life for this :( Commented Jan 9 at 14:55
42

My favorite one is CTRL + P then CTRL + O

This works by default, no extra configuration needed. ^P will let you switch to the last command and ^O will let you execute current line

Note that CTRL + O can be used for as many times as you want

8
  • 2
    ^O does not do anything on my Mac.
    – Snowcrash
    Commented Jul 14, 2018 at 22:59
  • 1
    @Snowcrash Try ^J
    – daisy
    Commented Jul 20, 2018 at 5:48
  • that just echoes a blank line even if I've done an ls or pwd previously.
    – Snowcrash
    Commented Jul 20, 2018 at 8:54
  • @Snowcrash It's ^P then ^J ...
    – daisy
    Commented Jul 20, 2018 at 9:05
  • Ctrl + P does not work on HP-UX (I don't know which shell it is using). The workaround is to invoke `zsh'. Commented Jul 31, 2018 at 11:35
17

Sure! Since you're used to vi keybindings, why not configure your shell to respond to them? For bash, put this in your ~/.inputrc:

set editing-mode vi

Running instances of bash will not re-read the file, so log out and back in.

zsh will even detect this for you: if none of your startup scripts force the editing mode one way or the other using bindkey and if your $EDITOR environment variable is detected to contain vi, then it will automatically enable vi keybindings. If you need to force it, put this in your ~/.zshrc:

bindkey -v

Thereafter, use ESC as usual to enter command line and k and j to move up and down.

ALSO: The default shell bindings in most shells are the emacs bindings, so actually Crtl-P and Ctrl-N should already work without you having to change anything.

0
12

With any POSIX shell implementing the User Portability option (includes ksh, zsh, bash, yash), you can also use the fc command:

fc -e : -1

See an example:

$ echo "hello"
hello

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

More info in Execute a range of commands from history's answer by Jonathan Leffler.

7

I find I need to redo commands as super user often, so

sudo !!

redoes the previous command as if I had remembered to type sudo in the first place.

1
  • 2
    I really like this, also looks like a good response to "authorization denied". "I meant sudo ffs!" Commented Aug 1, 2014 at 11:20
6

For all you Mac iterm2 users:

You can bind +R to 0x0C 0x10 0x0d. This will clear the terminal and run the last command.

iterm 2 key preferences

2
  • Is there any way to repeat the last command without clearing the terminal?
    – Luke Davis
    Commented Jan 16, 2018 at 1:41
  • Ah, nevermind: for anyone reading this, to repeat without clearing the terminal, use 0x10 0x0d (i.e. omit the 0x0C).
    – Luke Davis
    Commented Jan 16, 2018 at 1:42
5

The ksh shell has a default alias r that repeats the most recent command. It is bound to fc -s:

alias r='fc -s'

Interestingly, the bash documentation for the fc builtin (help fc, and also in the manual itself) even mentions this, but it's not a default alias in that shell:

A useful alias to use with this is r='fc -s', so that typing r cc runs the last command beginning with cc and typing r re-executes the last command.

In bash, this would also work even if you have turned history expansions off with set +H.

In the zsh shell, there is a r builtin that is documented to be the same as fc -e -.

The fc utility is a POSIX standard utility.

3

With csh or any shell implementing csh-like history substitution (tcsh, bash, zsh), you can also use the !<beginning of command> to call the last command beginning with <beginning of command>.

for example if you ran

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

!ta would execute tail file.txt

1
  • This answer def needs more attention!
    – vdegenne
    Commented Jan 29, 2020 at 2:29
1

you can use !n to execute nth command in terminal. where 'n' is line no of history command.

3
  • Which shell expands !? to the last command? Are you sure you're not mixing it up with !! (which has already been covered in other answers)? Commented Feb 18, 2018 at 16:53
  • sorry, actually i was experimenting this command at that time. please check edited answer. @AnthonyGeoghegan
    – Ravi Sevta
    Commented Feb 18, 2018 at 17:45
  • This was the shortcut I was looking for. Thanks!
    – le_daim
    Commented Aug 12, 2019 at 12:23
1

tl;dr !! just appends the last command to your current command. <backtick>!!<backtick> executes the last command and appends the output to your current command.

There are actually 2 variants:

  1. The last command itself
  2. The result of the last command

Let me show you 2 examples:

Example 1

$ mkdir /test
mkdir: /test: Permission denied

$ sudo !!
sudo mkdir /test
Password:

As you see above, I'm executing a command and essentially just appending the last command.

Another variation

Example 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"
0
1

There are several layers in which you can ask for the last command.

Line editor

The line editor (where you type your commands) is provided directly by ksh, by the library readline in bash, and by the library zle in zsh. Other shells, like dash may not have an editing library to understand this keys (unless compiled with the --with-libedit option enabled) .

This work in ksh, bash, zsh:

Ctrl-P # Emacs mode (previous)
Ctrl-N # Emacs mode (next)
ESC-k # vi mode ESC to go to command mode and k for up
ESC-j # vi mode ESC to go to command mode and j for down

history

The history system provided by many shells allow the expansion of some shortcuts:

!!    # bash and zsh, may be provided by `alias \!\!='fc -e -'` in ksh.
!-1   # bash and zsh only

commands

There are some commands which are able to retrieve history commands.

Like the quite verbose command (only to print):

history 2 | head -n-1

or the older and therefore usually more portable fc command (directly re-executes):

fc -e - -1

Or maybe the simpler fc -s -1, but zsh doesn't accept such option for fc.

If you want to only print the command, use: fc -nl -1 -1.

To edit, set FCEDIT to a text editor (ex, ed, emacs, vi, etc.) and use fc directly: fc -1.

1

The happy hacking keyboard does have arrow keys, just not dedicated arrow keys. They can be used with:

  • Fn and [ for Up
  • Fn and ; for Left
  • Fn and ' for Right, and
  • Fn and / for Down.

This is indicated with the front-printed legends on these respective keys as seen on this blog.

0

When I am using a good xterm emulator, e.g. putty, my favorite way to proceed is to select the command including line feed, copy it to clipboard and then use right click on the mouse to paste it. This repeats the command in a single click. This also works fine for a sequence of commands separated by semi-colons.

0
  • Type History and note the number in front of the command that you to execute and use !number

  • You can also use !-1 (1 being the last command you execute, replace it with the count number that you get when you do it from below keeping the last executed as 1 )

  • !-2 (second last and so on)
0
0

One of my favorites shortcuts is: hold Ctrl and P+J It's like up and enter but in a smoothie way

Here you can find more shortcuts https://cheatography.com/gamejia90/cheat-sheets/basic-bash/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .