Top
Best
New

Posted by refp 5 days ago

A shell exclamation mark is not for yelling. Be lazy(refp.se)
80 points | 34 comments
userbinator 3 hours ago|
Every time someone brings this up, I think "oh right, I could do that" and then immediately forget. Especially if you can type quickly, it's easier to just "drive straight ahead" with the command you want, than add another "mental branch" to interrupt the flow. For the same reason I'll often Ctrl+C and start again instead of trying to backspace and correct.
Retr0id 19 minutes ago||
"sudo !!" is quite firmly burnt into my muscle memory, but the whole rest of the time when I type an exclamation mark I mean it literally, and I get annoyed when it turns into a syntax error of some variety.
adityaathalye 1 hour ago|||
As an Emacs using degenerate, `M-.` is my friend. `!` is too awkward on the keyboard.
squigz 38 minutes ago||
As someone who can type rather quickly, I disagree. It can take some time to internalize, but once you do, it's much faster.

Same with Ctrl-C - once I got used to navigating by word instead of by character to correct things, it became much faster than starting over.

idoubtit 17 minutes ago||
Decades ago, I was taught to use `!` and Co, by a Linux user who was fond of the `sudo !!` trick. Then I switched from this implicit interpolation to explicit shortcuts, and I'm glad I did.

As suggested in the FAQ at the bottom, instead of !… you can use ctrl-r. Or better, optionally type the first letters then alt-p or "up". It's more powerful and more extensible. Other shortcuts, like alt-., allow navigating into the past parameters.

With up, alt-p, alt-. and such, the command line displays the real command. The !… magic is more error-prone and ambiguous; with zsh, I'd suggest hitting TAB to expand the magic into a static text.

I would add other entries to the FAQ: When I enter `sudo !!` will it be stored unchanged in the shell history, or stored after interpolation of `!!`? When I start a command line with a space, so that zsh does not put it in the shell history, will !… also ignore that line? Is `!$` recursive?

DrNefario 18 minutes ago||
I'm much too lazy to memorise what all of these do, I'd rather just use fish wherever I can. Some combination of typing, arrow keys, and alt+arrow keys is always enough for me to find that thing I want to avoid fully retyping.

P.S. The alt+s shortcut is much quicker than writing sudo !!

inigyou 15 minutes ago||
This is for teletypewriters. For those of us with interactive electronic video displays, we can use up-arrow to recall the last command or Ctrl-R to search history, then edit the recalled command.
Terr_ 3 hours ago||
Rather than a sense of "cool" or "useful" somehow I end up just feeling despair at how organically convoluted it is to determine what something on a command-line really does. To be fair, I've always been biased towards "only the simplest scripts should be in shell languages."

This also adds an intriguing new dimensions to reviewing/verifying shell commands as benign and correct... How long until LLMs start (ab)using the trick in little requests they want me to approve?

CoastalCoder 1 hour ago||
Maybe it's a bit like current C++ language spec:

There's enough complexity in the language spec that most people stick with a (fairly shared) subset.

Bash can be very powerful, but IMHO there's a certain point where I find it saner to accomplish the same thing via Python.

magarnicle 1 hour ago||
man bash. That's the secret. man bash.
zoky 29 minutes ago||
The cool thing about programming languages like Ruby is that they’re very conducive to one-liners. You can use them to generate bash statements that you can then pipe back to bash. `ls | ruby -nle 'puts "mv #{$_} #{$_.gsub(/_/, ".")}"' | bash` is a pattern I use all the time, for example. Easy way of generating complex bash statements without having to bother with the bash man page.
hnlmorg 1 hour ago||
I’ve been burnt before using ! and forgetting what command I typed previously, thus invoking the wrong command line.

!! is handy for the sudo example, but beyond that, I tend to prefer pressing the up arrow to cycle through the history rather than picking the first item. Eg:

  !ssh
vs

  ssh[up]

It’s the same number of key strokes but less error prone
refp 37 minutes ago||
Worth noting that `ssh[up]` isn't available by default in bash nor zsh — though it wouldn't surprise me if helpers such as oh-my-zsh enables it for you. `ssh[up]` is certainly an awesome feature — though (perhaps sadly) not default behavior.

> I've been burnt before using ! and forgetting what command I typed previously

If you want to make sure you do not execute commands you did not intend to, the section linked below is a great start:

- https://refp.se/articles/your-shell-and-the-lazy-exclamation...

You may also look into `magic-space` which makes the expansion of event-designators happen inline, I thought about including it but the article felt long even without it.

Thanks for reading the article, I hope it was a worthwhile read even with alternate workflows elsewhere!

hnlmorg 3 minutes ago||
Thanks for the tips. These days I don’t use sh derivatives as my primary shell and the shell I do use has a few features to make command search more ergonomic and safer. But these are useful tips nonetheless
CoastalCoder 1 hour ago|||
Agreed. I especially cringed at the author's example of mixing that with "sudo".
refp 1 hour ago||
the "mixing of sudo"-example is using `!!`, which as explained is the immediately previous command, a little confused how that translates to the "execute command somewhere in the history" argument?
CoastalCoder 10 minutes ago||
I suppose it depends on the kinds of mistakes to which one is prone.
pwdisswordfishq 36 minutes ago||

    bind space:magic-space
Joker_vD 3 hours ago||
sigh The usability of ! versus Ctrl+R in a shell is pretty much the same as the usability of ed versus vi, or moving files around using cp/mv versus using Midnight Commander or the like: in the first case, you have to accurately remember the past (which for many people is pretty difficult); in the second case, you don't have to, because you always have an immediate view of the state of the system and the preview of the effect you're about to incur.

And yeah, I've done editing with ed; it definitely beats "cat >file.txt" and copying parts around with head/tail and retyping the corrections manually, sure, and it works in every environment that can take line-oriented input from the user (so, literally everywhere), but that's about as much praise as I can give it.

refp 49 minutes ago||
> you have to accurately remember the past

From personal experience I rarely reach for event-designators beyond the current viewport of the terminal. Referring to a command beyond that is, as you very much correctly point out, an easy way to get behavior you don't want. However, if you are always referring to things that are near-memory or even still directly visible in your terminal buffer — the gun-to-foot ratio becomes manageable. I use many (many) of these daily without issues, but it does require some additional discipline.

Also, and this I find important to note, `!!` and `!$` sit outside of the memory argument as they always refer to the last command and last-command's last-argument respectively — as such there shouldn't be any recall related problems (unless you are context switching and come back to a shell in a state you don't remember).

A common occurrence when my posts acquire attention is that I retroactively realize that some things could have been conveyed better; I read every comment and yours is a blessing in disguise to improve future writing.

Thanks for reading the article, and thanks for indirectly making me a better writer!

---

EDIT:

by the way, for what it's worth, the below linked section describes how to effectively explicitly confirm what you would run as a safety measure if unsure:

https://refp.se/articles/your-shell-and-the-lazy-exclamation...

Joker_vD 5 minutes ago||
Frankly,

    !-2 && !!
and its variations (like '!-2 | !!') is pretty much the most use I've gotten out of this feature.
Terr_ 3 hours ago||
> in the first case, you have to accurately remember the past

Right, as a matter of (relatively trivial) cybernetics between man and machine, it rests on the weaker parts of the human.

TBF, it'd make a lot more sense if every command on screen (or given the timescale perhaps teletype paper prinout) was already labeled with the necessary number.

petschge 2 hours ago||
You can just add something like (\\!) in your PS1 and get just that.

PS1="(\\!) \[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ "

as a full working example

csydas 3 hours ago||
! calls are vital for your sanity if you ever do remote support

trying to write shell commands on a hypervisor console window within a remote session on a jump box is excruciatingly laggy and annoying, and that's assuming your remote session connection to the client is behaving well in the first place

crabbone 1 hour ago|
I have a script that does virsh send-key of whatever I need to send. In my specific case the motivation was the mismatch between my keyboard layout and the keyboard in the VMs, so I couldn't send M-# or even C-... into the VNC console.

I'm way too paranoid to ever use "!". I want to see the command I'm sending.

grimgrin 2 hours ago||
i love the mkdir example, so i’m going to exercise that muscle and see where it goes

and yeah ^r works, though i often type a few chars and ^p till i get the match. history-search-backward in your inputrc, iirc

edit: on a computer now :) my `if emacs` block, allowing arrows or ^n/^p to run through history. so for e.g., type "tar" and now as you shift through history with :binding:, it only shows history that began with "tar"

    $if mode=emacs
    "\e[A": history-search-backward
    "\e[B": history-search-forward
    "\C-p": history-search-backward
    "\C-n": history-search-forward
    ...
    $endif
zzril 2 hours ago|
That one was always worth its own function for me.

``` mkcd() { mkdir -p -- "$*" && cd -- "$*" } ```

rixed 3 hours ago|
If you find this interesting, don't wait for a random blogpost to appear by chance on HN, go read some manage today!
More comments...