You know how there are weird tricks with computer stuff that you think everyone knows but they don't? I live learning and teaching new things like those when they come up.
Today's was the carat substitution in bash. It probably works in other shells too but IDK, I'm too old to learn a new shell.
The way it works is fairly similar to the / in sed or similar. You can use them to run the previous command but with a string substitution.
For example, let's say I entered this command:
dig A cascadiacrow.org
When it fails to resolve, I realize it was a .com domain. Rather than retyping the command, or hitting the up arrow to change the previous command, you could do this:
^org^com^
And it would run:
dig A cascadiacrow.com
Kind of cool with those one liners you spend way too much time on and find a typo.
Anyway, I used it and someone thought it was magic so if it's new to you too, happy Monday.
Jonathan Lamothe likes this.
reshared this
Zimmie
in reply to :rainbowCrow: • • •I’m a big fan of ‘!!’, which runs the previous command again.
Permission denied?! Fine! ‘sudo !!’
:rainbowCrow:
in reply to Zimmie • • •Rachel Rawlings
in reply to :rainbowCrow: • • •@bob_zim I just always wish ^com^org^g worked. It takes me forever to remember
!!:gs/com/org/
and usually requires a reminder from stack overflow
Bruce Heerssen
in reply to Zimmie • • •@bob_zim
I also like using history for that.
Run 'history', find the line number for the command you want, then type ! followed by that number, eg: !233 or something.
David Schuetz
in reply to Bruce Heerssen • • •@bruce @bob_zim And !$, to repeat the argument from the last command.
There’s a ton of great shell tricks out there.
Scherzog von Beast Oil
in reply to Bruce Heerssen • • •@bruce @bob_zim Speaking of history, at least in bash, if you put one or more spaces before your command, that command does NOT get saved to your command history. 👻
This is sometimes useful when you have to repeatedly run a very long command and then want to do a one-time test of some variation of it without breaking your "up+enter" flow.
The Doctor
in reply to Zimmie • • •`alias holdmybeer='sudo !!'`
Kim Spence-Jones 🇬🇧😷
in reply to The Doctor • • •🤣
Peter Linss
in reply to The Doctor • • •GitHub - nvbn/thefuck: Magnificent app which corrects your previous console command.
GitHubfuzzyfuzzyfungus
in reply to Zimmie • • •@bob_zim An 'onomatopoeia' is when the word sounds like the sound it describes. Anyone know if there's a term for something resembling the emotion it conveys?
"!!" to mean "do what I told you last time again" seems to perfectly capture the spirit in which it is likely to be written.
June
in reply to Zimmie • • •don Elías (como los buses) 🥨
in reply to :rainbowCrow: • • •I like using $_ in bash
It refers to the final argument of the last command, useful when such argument is very long, like:
mkdir /var/log/very/long/dir/path
chmod 2750 $_
cd $_
There $_ holds /var/log/very/long/dir/path
When writing this, I was thinking that something feels special about it, and just remembered that this is a trick that a human being taught me years ago, not something I read in a manual.
mab
in reply to don Elías (como los buses) 🥨 • • •@donelias
Fun fact: on the surface, both `!$` and `$_` seem to do the same thing, pop the last argument of the previous command, but the former brings it up **after shell expansion** while the latter brings it up **before shell expansion**.
For example:
```
~$ ls fooba*
test1
test2
test3
~$ ls !$
test1
test2
test3
~$ ls $_
ls: fooba*: No such file or directory
```
Or even more speaking:
```
~$ echo "$(date -z UTC)"
Tue Jul 14 14:48:25 UTC 2026
# wait a few seconds
~$ echo 'With $_\t' $_ '\nWith !$\t' !$
With $_ Tue Jul 14 14:48:25 UTC 2026
With !$ Tue Jul 14 14:48:39 UTC 2026
```
Here, `$_` was expanded to what was actually received by the command, whereas `!$` was expanded to what you actually typed, before the shell interpreted it.
@cR0w
aburka 🫣
in reply to mab • • •:rainbowCrow:
in reply to don Elías (como los buses) 🥨 • • •mkdirand wand tocdto it, just like your example. Otherwise I forget about it until I use Powershell again.Craig
in reply to :rainbowCrow: • • •Hey Gus
in reply to don Elías (como los buses) 🥨 • • •@donelias jfc I always forget this.
Also reading the bash docs: why tf would I ever need this feature.. oh right..
The Orange Crow
in reply to :rainbowCrow: • • •Mx. Aria Stewart
in reply to :rainbowCrow: • • •:rainbowCrow:
in reply to Mx. Aria Stewart • • •Garrett Wollman
in reply to :rainbowCrow: • • •:rainbowCrow:
in reply to Garrett Wollman • • •Craig
in reply to :rainbowCrow: • • •DamonHD
in reply to Garrett Wollman • • •@wollman tcsh remains my preferred interactive shell, and allows all the above tricks. Yes, I am old!
!$ and !! and up-arrow and history and !nnn (for history entry nnn) are probably the ones I use most, many many times each day.
Howard Chu @ Symas
in reply to DamonHD • • •temporalthought
in reply to :rainbowCrow: • • •RLB!
in reply to :rainbowCrow: • • •Adam Katz
in reply to :rainbowCrow: • • •if you type
Alt+Dot(orEsc,Dot), it shows the previous command's final argument. Do it again for the command before that.Alt+{2,Dot} (holding Alt, press 2 then Dot) gets the penultimate argument. Keep holding Alt so you can press Dot to go to older commands.#bash & #zsh. Note, some terminals don't support the Alt implementation. Esc can't enumerate.
Ole
in reply to :rainbowCrow: • • •:rainbowCrow:
in reply to Ole • • •Anthony Stanton
in reply to :rainbowCrow: • • •:rainbowCrow:
in reply to Anthony Stanton • • •Oriel Jutty
in reply to Anthony Stanton • • •shopt -s histverify. Or to reëdit a failed substitution,shopt -s histreedit.gnu.org/software/bash/manual/h…
The Shopt Builtin (Bash Reference Manual)
www.gnu.orgSplinux
in reply to :rainbowCrow: • • •> I'm too old to learn a new shell.
Progression be like:
I'm too old to learn anew.
I'm too old to learn.
I'm too old.
edit: by the way, the string substitution in bash is probably the Never Ending Story (wouwo wouwo wouwooo) in terms of how many ways one can do that.
And yes, i didn't know that one. Handy 👍🏻
Ryan
in reply to :rainbowCrow: • • •schnittchen 🏳️🌈
in reply to :rainbowCrow: • • •Malcolm Herbert
in reply to schnittchen 🏳️🌈 • • •:rainbowCrow:
in reply to schnittchen 🏳️🌈 • • •Andreas Neustifter
in reply to schnittchen 🏳️🌈 • • •Howard Chu @ Symas
in reply to :rainbowCrow: • • •Malcolm Herbert
in reply to :rainbowCrow: • • •:rainbowCrow:
in reply to Malcolm Herbert • • •Malcolm Herbert
in reply to Malcolm Herbert • • •VenturaHwyBill
in reply to :rainbowCrow: • • •Fish Id Wardrobe ⁂
in reply to :rainbowCrow: • • •i can confirm that the tilde trick works in zsh, too, at least for me; it probably depends on your config file.
!! works too, but !$ does not. of course you can probably use the tilde trick, instead.
robinmuller
in reply to :rainbowCrow: • • •In league with the future
in reply to :rainbowCrow: • • •not new to me. But thank you!
Brings up long forgotten memories of learning shell at university where we didn’t have full screen editing. !, !!, ^, and ex were regular friends.
Richard Buckle
in reply to :rainbowCrow: • • •:rainbowCrow:
in reply to Richard Buckle • • •nokke
in reply to :rainbowCrow: • • •thanks, did not know this trick.
One that I use to share - the comma. It can be used in a lot of places in a "from - to" mode.
mv file.txt{,md} == rename
mv file{.txt,} == strip
mv file{,.txt} == unstrip
...etc. Not a secret, useful in all sorts of work.
Lien Rag
in reply to :rainbowCrow: • • •github.com/watzon/ohshit
GitHub - watzon/ohshit: Oh Shit! is the command fixer you didn't know you needed. Inspired by thefuck.
GitHub:rainbowCrow:
in reply to Lien Rag • • •thefuckand they thought it was fun.schrotthaufen
in reply to :rainbowCrow: • • •schrotthaufen
in reply to schrotthaufen • • •grechaw
in reply to :rainbowCrow: • • •Allen but one of the good ones
in reply to :rainbowCrow: • • •Oh this will be very useful! Thanks!
I've played around briefly and found that if there's more than one match it only substitutes the first one. Are there options to do more, or am I getting greedy?
:rainbowCrow:
in reply to Allen but one of the good ones • • •sed. So something like^foo^bar^3but I don't remember for sure. I'll try to remember to play around with it later.Breizh
in reply to :rainbowCrow: • • •Bash history expansion always looked very powerful, but also very complex at the same time, so I didn’t bother learning it.
This particular shortcut looks like it can be useful, that being said.
:rainbowCrow:
in reply to Breizh • • •Chris | cy
in reply to :rainbowCrow: • • •github.com/nvbn/thefuck
GitHub - nvbn/thefuck: Magnificent app which corrects your previous console command.
GitHubBill
in reply to Chris | cy • • •:rainbowCrow:
in reply to Chris | cy • • •brib -> EMF 2026
in reply to :rainbowCrow: • • •This is a cool trick!
One note: When I shared it, one of my followers felt like there was an implication here that Bash/shell scripting is more widely used than it is. (The xkcd "we forget most people only know x, y, and of course z" strikes again).
Would it be possible to rephrase this slightly to emphasise this toot is specifically targeted at people who know Bash?
:rainbowCrow:
in reply to brib -> EMF 2026 • • •@brib I tried:
Coral 😷
in reply to :rainbowCrow: • • •Linus Kromwell
in reply to :rainbowCrow: • • •The Bash Hackers Wiki
flokoe.github.ioLinus Kromwell
in reply to Linus Kromwell • • •Parameter expansion - The Bash Hackers Wiki
flokoe.github.iojordan
in reply to :rainbowCrow: • • •my favorite
bashtrick, for when you've really boned up and deletedls:echo *(
echois a built-in and the shell handles the wildcard internally):rainbowCrow:
in reply to jordan • • •ls? 😅aburka 🫣
in reply to :rainbowCrow: • • •UNIX Recovery Legend
www.ecb.torontomu.caAdam Katz
in reply to jordan • • •@jordan I had that issue upgrading Ubuntu to 26.04 (from a much older release), which moved from GNU to UUtils Coreutils but forgot to install the replacement. I went to the old standby of
echo *but then also remembered that Debian systems all include BusyBox. Just runbusybox lsinstead.This was essential as various dpkg post install scripts needed
ln,cp,rm, and more, so I temporarily symlinked (busybox ln …) these commands, in /bin, tobusybox. Voila, the upgrade could complete.Vinnewed Goblin
in reply to :rainbowCrow: • • •Buttered Jorts
in reply to :rainbowCrow: • • •:rainbowCrow:
in reply to Buttered Jorts • • •Frost, ᛁᛊᛟᛚᚠᚱ 🐺❄️&
in reply to :rainbowCrow: • • •Huh.
zsh has !!:s/org/com/ . I don't know if it does the caret thing.
Richard "mtfnpy" Harman (he/him)
in reply to :rainbowCrow: • • •Have you got a window somewhere off screen in Windows, where you can't grab it with the mouse to drag it around?
This has worked since windows 3.x, possibly earlier: Alt+Space, m, tap an arrow key, then move your mouse. Tapping an arrow key "sticks" the window to your mouse cursor.
If this didn't work, the window might be maximized and needs to be Restored first: Alt+Space, R. Then do the above.
:rainbowCrow:
in reply to Richard "mtfnpy" Harman (he/him) • • •Just a trash panda 🦝
in reply to Richard "mtfnpy" Harman (he/him) • • •@xabean Use this all the time! Before they removed the feature, I also used to use "Cascade Windows" from the task bar when this happened.
The cascade button also worked for hidden dialog boxes. Still haven't found a replacement for that trick with regard to those.
Jernej Simončič �
in reply to Richard "mtfnpy" Harman (he/him) • • •gürkan �’
in reply to :rainbowCrow: • • •I hope everyone knows ctrl-a throws you to beginning of the line & ctrl-e to the end.
> + I was too lazy for any of the "sudo !!" solutions, I mostly realize that I forgot sudo _while_ typing the command. So bound that to double-esc (also brings last command if prompt is empty):
)
zsh: paste.gurkan.in/nonundulating-…
bash: paste.gurkan.in/unconcentrativ… (not tested as much, only if I have to
mark
in reply to :rainbowCrow: • • •Jordan
in reply to :rainbowCrow: • • •Andreas Neustifter
in reply to :rainbowCrow: • • •E.g `ls file.{c,h}` expands the file argument once with c, then with h, so effectively running `ls file.c file.h`.
Very useful for comparing the same file in different folders: `diff -u {old,new}/somefile.ext`.
And much more targeted than most globbing, e.g. `git add file.*` usally complains about my vi backup files but `git add file.{c,h,proto}` targets exactly what I want.
:rainbowCrow:
in reply to Andreas Neustifter • • •forloops.Hey Gus
in reply to Andreas Neustifter • • •@astifter this is about as much as I have in long term memory for expansion haha
tldp.org/LDP/abs/html/paramete… also honorable mention for substitution which in my opinion is second only to `trap` for being the most arcane but useful thing.
Parameter Substitution
tldp.orgcoldclimate 🔜 EMF2026
in reply to :rainbowCrow: • • •BEDNAR~1
in reply to :rainbowCrow: • • •infosec.exchange/@BednarTildeO…
RE: infosec.exchange/users/BednarT…
BEDNAR~1 (@BednarTildeOne@infosec.exchange)
BEDNAR~1 (Infosec Exchange)Sharkfie
in reply to :rainbowCrow: • • •I would like to subscribe to more "useful things I'll forget" facts
CTRL + A (beginning of line), CTRL + E end of line, CTRL + K (kill, erase to the end of the line), CTRL + D (delete a character forward).
These are pretty common but I only learned some of them from Emacs.
Sharkfie
in reply to Sharkfie • • •Jonathan Lamothe
in reply to Sharkfie • •like this
:rainbowCrow: and Sharkfie like this.
Keith Dawson
in reply to :rainbowCrow: • • •I learned this trick in the early 1980s at DEC, from Ken Arnold, who was in my department. Except Ken used the comma character instead of carat, saving a few keystrokes. The magic in .login is:
set histchars=\!,
(cshrc / tchsrc syntax, not bash.) I have carried this incantation forward in all my Unix-like environments for 40+ years.
thedoh 🇨🇦
in reply to :rainbowCrow: • • •Let's say you have two container runtime engines but you want to prefer one over the other:
which podman docker | head -n1
This will prefer whichever is first in the list, podman, in this case. Why is it useful? Say you're creating a Makefile and you need to interact with a container. Some people use podman and others use docker. In your Makefile you can put:
CONTAINER_RUNTIME ?= $(shell which podman docker | head -n1)
Then you can refer to $(CONTAINER_RUNTIME) in the Makefile target to use either podman or docker, (or something else, but that's for another toot).
(as a disclaimer, I work for Red Hat, which maintains Podman, but I do not work on that team.)
thedoh 🇨🇦
in reply to thedoh 🇨🇦 • • •Another one:
Let's say that you sometimes have to paste sensitive things into your terminal, like login strings, or credentials.
If you paste them in normally, they'll show up in your history, and that could be bad. That can be mitigated to some extent in Bourne shell with:
export HISTCONTROL=ignorespace
Now, you can put a leading space in front of your sensitive command and it won't show up in your history:
` curl -u username:password https://www.example.com/login`
(put in backticks to make it obvious there's a leading space)
James Seward
in reply to thedoh 🇨🇦 • • •@thedoh on macOS you can run something like
eval $(pbpaste)
to run what’s in your clipboard without the command itself going in your history. You sometimes need “s around the parameter (like if it’s multiline maybe?). I’m sure Linux has an equivalent to pbpaste, but I don’t know what it is.
thedoh 🇨🇦
in reply to James Seward • • •@jamesoff This one you have to be careful of because it can open you up to clipboard shenanigans, but it's a good one!
A favourite of mine is related to that:
some-command | pbcopy
James Seward
in reply to thedoh 🇨🇦 • • •@thedoh yeah I use that a bunch too 😀
And of course, only for clipboard contents you trust. I mostly use it for things like setting temp AWS creds vended by a portal (for times I don’t have sso or other mechanisms)
Erik Osterholm
in reply to :rainbowCrow: • • •My favorite that most people don't seem to know is that substitution in sed (and vim) doesn't require slashes.
Most people use something like 's/search/replace/'
But you can use any character for the delimiters, such as: 's#search#replace#'
This is very handy when editing paths or anything else with slashes in the search or replace text.
:rainbowCrow:
in reply to Erik Osterholm • • •kajer :unsane:
in reply to Erik Osterholm • • •@erikosterholm
You mean to tell me that replacing doesn't need a convoluted string of escape characters?!?!!?
wtf
Jernej Simončič �
in reply to Erik Osterholm • • •@erikosterholm I usually use commas.
This also works in perl (everywhere where slashes are used; for bare matching, you can use
$m =~ m,whatever,; in place of$m =~ /whatever/).Szymon Sokół 🇵🇱🇪🇺🇺🇦
in reply to :rainbowCrow: • • •ADHDruid
in reply to :rainbowCrow: • • •T.F.G.
in reply to :rainbowCrow: • • •First time doom-scrolling on Mastodon for me. You're all amazing!
Will have to invest my first 2 hours at work tomorrow to keep up with the replies.
:rainbowCrow:
in reply to T.F.G. • • •