conv.

All stories
TechRunning 3d

Shell history expansion: a guide to lazy command reuse with exclamation marks

Tutorial on using bash/zsh event designators to avoid repeating commands and arguments.

Conversation activity · last 4 days peak 5/hr

Peak 5 items in one hour at Aug 7, 7 AM; 55 items over 4 days Aug 6, 10 AM — 1 itemAug 6, 11 AM — no itemsAug 6, 12 PM — no itemsAug 6, 1 PM — no itemsAug 6, 2 PM — no itemsAug 6, 3 PM — no itemsAug 6, 4 PM — no itemsAug 6, 5 PM — no itemsAug 6, 6 PM — no itemsAug 6, 7 PM — no itemsAug 6, 8 PM — no itemsAug 6, 9 PM — 1 itemAug 6, 10 PM — no itemsAug 6, 11 PM — no itemsAug 7, 12 AM — 2 itemsAug 7, 1 AM — 2 itemsAug 7, 2 AM — no itemsAug 7, 3 AM — 1 itemAug 7, 4 AM — 1 itemAug 7, 5 AM — 4 itemsAug 7, 6 AM — 3 itemsAug 7, 7 AM — 5 itemsAug 7, 8 AM — 1 itemAug 7, 9 AM — no itemsAug 7, 10 AM — 1 itemAug 7, 11 AM — 3 itemsAug 7, 12 PM — 4 itemsAug 7, 1 PM — 4 itemsAug 7, 2 PM — 1 itemAug 7, 3 PM — no itemsAug 7, 4 PM — no itemsAug 7, 5 PM — no itemsAug 7, 6 PM — no itemsAug 7, 7 PM — no itemsAug 7, 8 PM — no itemsAug 7, 9 PM — no itemsAug 7, 10 PM — 1 itemAug 7, 11 PM — 1 itemAug 8, 12 AM — no itemsAug 8, 1 AM — 3 itemsAug 8, 2 AM — no itemsAug 8, 3 AM — no itemsAug 8, 4 AM — no itemsAug 8, 5 AM — no itemsAug 8, 6 AM — 1 itemAug 8, 7 AM — 1 itemAug 8, 8 AM — 2 itemsAug 8, 9 AM — 1 itemAug 8, 10 AM — 3 itemsAug 8, 11 AM — no itemsAug 8, 12 PM — 1 itemAug 8, 1 PM — no itemsAug 8, 2 PM — 1 itemAug 8, 3 PM — no itemsAug 8, 4 PM — no itemsAug 8, 5 PM — no itemsAug 8, 6 PM — no itemsAug 8, 7 PM — no itemsAug 8, 8 PM — no itemsAug 8, 9 PM — no itemsAug 8, 10 PM — no itemsAug 8, 11 PM — no itemsAug 9, 12 AM — no itemsAug 9, 1 AM — no itemsAug 9, 2 AM — no itemsAug 9, 3 AM — no itemsAug 9, 4 AM — 1 itemAug 9, 5 AM — 1 itemAug 9, 6 AM — 2 itemsAug 9, 7 AM — no itemsAug 9, 8 AM — no itemsAug 9, 9 AM — 1 itemAug 9, 10 AM — no itemsAug 9, 11 AM — 1 itemAug 9, 12 PM — no itemsAug 9, 1 PM — no itemsAug 9, 2 PM — no itemsAug 9, 3 PM — no itemsAug 9, 4 PM — no itemsAug 9, 5 PM — no itemsAug 9, 6 PM — no itemsAug 9, 7 PM — no itemsAug 9, 8 PM — no itemsAug 9, 9 PM — no itemsAug 9, 10 PM — no itemsAug 9, 11 PM — no itemsAug 10, 12 AM — no itemsAug 10, 1 AM — no itemsAug 10, 2 AM — no itemsAug 10, 3 AM — no itemsAug 10, 4 AM — no itemsAug 10, 5 AM — no itemsAug 10, 6 AM — no itemsAug 10, 7 AM — no itemsAug 10, 8 AM — no itemsAug 10, 9 AM — no itemsAug 10, 10 AM — no items 5 items · 7 AM
Aug 7Aug 8Aug 9Aug 10

Summary, timeline and people extracted by Claude from 55 items across 3 sources · 22h ago. Quotes are verbatim.

A technical article published on Lobsters explains how to use shell history expansion (exclamation mark syntax) to reuse previous commands and their arguments, promoting the DRY principle on the command line. The post sparked discussion about trade-offs between this feature and alternative shells like fish and nushell, with commenters debating usability, safety, and shell choice.

  • Shell history expansion using event designators (e.g. !!, !$, !ssh) allows reuse of previous commands and arguments, applying DRY principle to command-line work.
  • Practical concerns exist: commands expand invisibly before execution, creating safety risks for destructive operations like find or rm.
  • Alternative shells (fish, nushell) offer superior UX through auto-completion and explicit command editing, though bash/zsh remain preferred for legacy system compatibility and established workflows.

How it unfolded

  1. Reaction Bash defense offered

    Commenter wwfn argues bash deserves credit as a pleasant, sufficient tool with good ecosystem support like shellcheck.

  2. Reaction Alternative shells debate

    Commenter nicoco questions why developers use bash/zsh instead of more user-friendly alternatives, with responses discussing legacy system constraints and muscle memory.

  3. Reaction zsh history expansion behavior clarified

    Commenter leela shows that zsh stores expanded command versions in history, addressing one potential gotcha of the feature.

  4. Reaction Safety concerns raised

    Commenter spookylukey argues that editing commands interactively is safer than blind history expansion, citing destructive command examples.

  5. Reaction Fish shell alternative mentioned

    Commenter symgryph argues that fish shell eliminates the need for history expansion complexity through superior auto-completion.

  6. Reaction zsh tab-expansion capabilities noted

    Commenter banna demonstrates that zsh can expand event designators with tab completion, showing practical usability improvement.

  7. Report Article published on Lobsters

    User seb posts article titled 'A shell exclamation mark is not for yelling. Be lazy' explaining event designators and history expansion syntax in bash, csh, tcsh, and zsh.

What people are saying verbatim

“I know I might go to posix hell for this but I just use fish shell and I don't have to worry about all that nonsense. It just Auto completes nicely.”

symgryph, Lobsters commenter · Lobsters · Aug 7, 1:45 AM

“The problem with `!` is that— AFAIK— you can't see the expansion before running it.”

quad, Lobsters commenter · Lobsters · Aug 7, 7:30 AM

“Honestly, being able to quickly find and edit a previous line feels so much better than this for most cases, especially for commands that can be destructive.”

spookylukey, Lobsters commenter · Lobsters · Aug 7, 2:02 AM

“It is mindboggling to me that so many people use bash or zsh and not the user-friendlier alternatives like fish, nushell and other.”

nicoco, Lobsters commenter · Lobsters · Aug 7, 7:53 AM

“shell is the right tool for some programs and bash is more than just the sufficient almost-always-installed default, it's pleasant to work with once familiar!”

wwfn, Lobsters commenter · Lobsters · Aug 7, 10:31 AM

Voices from the web unedited

  • I know I might go to posix hell for this but I just use fish shell and I don't have to worry about all that nonsense. It just Auto completes nicely. I kind of take it for granted.

    symgryphunix3d ago54▲view on Lobsters ↗
  • you could also do: $ build-command $ run-command $ && cuts from cursor to beginning, and pastes.

    SeaBeautiful7577r/programming23h agoview on r/programming ↗
  • At least in zsh, the history only stores the expanded versions: ```shell % echo 'hello world' hello world % !:s/world/lobsters echo 'hello lobsters' hello lobsters % history ... 10052 echo 'hello world' 10053 echo 'hello lobsters' ```

    leelaunix3d ago27▲view on Lobsters ↗
  • It is mindboggling to me that so many people use bash or zsh and not the user-friendlier alternatives like fish, nushell and other. The arguments I hear against switching from the default usually fall into two categories: - (online) I need to use legacy systems where only (ba)sh is available and I'm not root, it's just easier to always use this…

    nicocounix3d ago12▲view on Lobsters ↗
  • I tried fish and sure it's obviously nicer than bash. I bounced off it because the syntaxes for things like for loops and variable assignments are quite different from sh and it was fighting my muscle memory.

    0x2ba22e11unix2d ago12▲view on Lobsters ↗
  • The problem with `!` is that— AFAIK— you can't see the expansion before running it.

    quadunix3d ago12▲view on Lobsters ↗
  • I don't like using these: they litter your history with history-dependent commands

    pbsdsunix3d ago12▲view on Lobsters ↗
  • Honestly, being able to quickly find and edit a previous line feels so much better than this for most cases, especially for commands that can be destructive - which is a large fraction of shell commands. As an example, I recently got bitten by the gotchas below: ``` find . -name '*~' find . -name '*~' -print0 find . -name '*~' -o -name '*.bak'…

    spookylukeyunix3d ago7▲view on Lobsters ↗
  • `zsh` handles tab-expansion for event designators to some degree… ``` $ zsh --version zsh 5.9 (arm64-apple-darwin25.0) $ ls ~/some/path ls: /some/path: No such file or directory $ mkdir !:$ # will expand to ~/some/path in the readline $ !z # again will expand to the most recent closest-match, i.e. 'zsh --version' ```

    bannaunix3d ago7▲view on Lobsters ↗
  • It is a hack, but I recently discovered ctrl+o in Bash (or I guess most readline stuff). After you recall a command from history (with ctrl+r, for example), ctrl+o executes it and moves to the next command in the history.

    koalaunix3d ago7▲view on Lobsters ↗