I use a shell every day. Almost always, I want to repeat a previous command, or repeat it after a slight modification. A very convenient way is to use arrow-up to get the most recent command back. Another common trick is to type ctrl-r and incrementally search for a previously used command. However, there are two other tricks for repeating previous commands that I use all the time, which are not as well known.
Escape-Dot (or !$)
Often you want to repeat only the last argument of the previous command. For example, suppose you want to run git diff path/to/tests, and then git add path/to/tests. For the second command, you can type git add escape-dot (escape followed by a period), and it gets expanded to path/to/tests (the last argument of the previous command).
I find that I quite often want to run another command on the same argument, and escape-dot is the most convenient way to do that. It also works to use !$ instead of escape-dot, but that is slightly harder to type, so I don’t use that anymore.
History With !
Sometimes I know I used a command a while back, but I don’t have a good string for searching with in ctrl-r (or maybe I will find too many unrelated hits in the search before I find the case I want). In this case I use history to get a list of the most recently used commands. Suppose I see the command I want to repeat at position 456 in the list. The !456 will rerun the command.
If I want to modify the command before running it, I type !456:p instead. Then I use arrow-up and then modify it before running it.
I like to keep a long history for my shell commands (several thousand entries). To still be able to scroll up in my shell without only seeing history entries, I have created an alias to only show the last 100 items in the list:
alias his=’history | tail -n 100; echo “Only last 100. For full, type: history” ‘
So I usually just type his, and get the last 100 commands listed.
I often want to edit what I have on the command-line before running the command (especially if I used arrow-up to get the most recent command). Here is what I use most frequently:
- ctrl-a Move to the beginning of the line
- ctrl-e Move to the end of the line
- ctrl-u Clear the line (before the cursor position)
- ctrl-w Delete the word before the cursor position
Most people I have worked with use both arrow-up and ctrl-r when repeating commands. However, very few are familiar with escape-dot and repeating commands from the history list. Since I use all four ways very frequently, I thought I would write a post to spread the word.
On the subject of command-line shortcuts, I also have to recommend the book Unix Power Tools. It contains over a thousand pages of well-organized, cross-referenced command-line tips. A fantastic resource for anyone who wants to up their command-line game.
I love $!, too. Probably because I have Unix Power Tools o my book shelf, too.
Great tip here on $! Related to that, I often find myself using !! (a.k.a. bang-bang) when performing sys admin tasks. Let’s say you just typed a command which requires sudo access, only you forgot to prepend sudo to the actual command. Now type, “sudo !!”, then Enter, and the entirety of the prior command will be appended to sudo. It’s been very handy for me, and I’m sure $! will occupy a similar space once I develop the muscle memory for its use.
I can’t think of too many LESS ergonomic keyboard shortcuts than Esc-dot. But in the interest of saving your readers some straining, I just wanted to point out that because Esc isn’t a modifier key, the keys don’t have to be pressed “at the same time”. You can simply type Esc, followed by a period.
This doesn’t make Esc-. any more convenient in terms of key placement, obviously. But it least leaves more options open, like typing it one-handed without being a contortionist.
Thanks, you’re correct! Good catch. I usually use my left hand for escape, and right hand for the period, but I agree, not particularly ergonomic 🙂
I just updated the post – it used to say: (escape and period pressed at the same time).
Just use Alt-. (Alt and period at the same time), works for me at least. I remember in Emacs it’s the same.
Huh! (Two years later, I finally notice this reply.) I never knew about that. Nice.
Weirdly though, at least on my keyboard — Fedora 32, standard US QWERTY layout in en_US — it only works with the LEFT Alt key. The (far more convenient to the . key) right Alt key, no dice. I just get a period. Wonder why that is?
Reddit discussion: https://redd.it/96oibw
I use ctrl+p to insert last command again into the current line.
Also for better history search I highly recommend FZF : https://github.com/junegunn/fzf
You will never go back to standard bash search.
As for history shortcuts- the best I like is Ctrl r
It lats you filter history with your input
Awesome! Will definitely use these! Thanks!
Nice ones, I didn’t know about !$ – thanks!
Thank you for ‘Esc .’ !!!
I’ve usually used !^ and !$ and ^old^new to fix typos eg. ^sudp^sudo
Additionally ^k opposite of ^u
Also ^x^e will launch your fav $EDITOR on the prompt ( HINT: vi ;-p)
also !* of course
If you want to repeat a command, you can type it out, hit enter, up, enter, up, enter, etc.
BUT! – Ctrl+o runs the command and leaves it at the prompt when it’s done, allowing for Ctrl+o, Ctrl+o, Ctrl+o …
The only reason I’d prefer the !$ over the esc + . is that on the new Macbook Pros that have the touch bar, the esc button has to be pushed and held in order for this command to work.
Question: Is there a way to repeat the last options used? For example, I tail -f ./log/some.log. Then if I say tail esc+. ?
You don’t need “history | tail -n 100”
You could use: “history | tail -100”
But history takes an arg: “history 100” …
Thanks, good points!
! can also be used to search and execute commands in the history.
Will execute the last command starting with a c.
It is convenient when you repeat 3-10 command in an unordered fashion, or if you want to re-run a few commands like:
Thanks for the tip Gunnar.
i keep a list of cmd line shortcuts here https://gist.github.com/yelinaung/849c78c40784c56e05f5a04dded9082d
might be useful sometimes 🙂
Great post thankyouu
From a Hacker News comment by layer8:
“Escape-dot has the benefits that (a) you immediately see what you’re getting and (b) you can repeat it to get the last argument of earlier commands.”