Monthly Archives: October 2021

Working the Bash Shell Like a Pro, Service Pack 1

“Man is a tool-using animal. Without tools he is nothing, with tools he is all.”
— Thomas Carlyle

“A fool with a tool is still a fool.”
— anonymous

“A fool with a tool is a dangerous fool.”
— anonymous

Five years ago, I wrote a popular post called “Working the Bash Shell Like a Pro“, a short collection of essential tips and tricks for working efficiently with the Bash shell.

Like everyone, during my daily interaction with Bash I use many “tricks”, however, only few of them qualify for being added to my original list. Now, the time has come for a small update.

1. The Bash Curse

As you already know from the previous post, ‘!#’ selects the “entire command-line typed so far”, ‘:1’ takes the first argument in the “command-line typed so far” and ‘:r’ strips the extension from it. So changing the file extension of a file can be done with a fairly short command-line:

which is — depending on the path length — a lot shorter than

Instead of picking the first argument by employing the ‘:1’ word designator you could equally well take the last argument by specifying ‘:$’. Why? There is only one argument typed so far (“some/long/path/to/file.c”), so the first argument is the last argument. Consequently, this achieves the same effect as the previous command:

You probably think that this hasn’t gained us much since the number of characters to type hasn’t changed. That’s true but Bash has a special shortcut for ‘!#:$’ which is ‘!#$’. This saves us the colon and hence one character:

Since ‘!#$’ looks like a grawlix, I call this character sequence the “Bash curse”. I often use it many times a day, whenever I need to reuse (parts) of the argument preceding the argument I’m currently typing.

2. Skipping History

All of the mentioned tricks depend heavily on Bash’s history feature. After all, we want to save time by reusing something we typed earlier. Sometimes, however, we would rather not mess up our history. Take this command-line, for example:

Let’s further assume that you need to execute this regularly, many times a day. If you haven’t created an alias for it, you’ll probably pull the CTRL-R stunt*, something which I also explained in my previous post. So you hit CTRL-R and start typing “conan install”. Immediately, the desired command-line shows up and all you have to do is hit “Enter” to execute it.

So far so good. Sometimes, however, you want to fine-tune the command-line, for instance, to do a release build:

After you executed this command, your next attempt to retrieve the original command-line via CTRL-R will first find the one containing ‘-s build_type=Release’ which is not what you want as you only rarely want to do release builds. So it would have been better if the release build command-line had never been recorded in Bash’s history.

Another example of when you don’t want something to be entered in you Bash history is when you provide passwords/credentials on the command-line, as in

So how do you avoid that something is remembered in Bash? It’s easy. Just put a single space before the command you are about to execute:

This concludes service pack 1. Don’t expect service pack 2 anytime soon…

*) If I had to give up all the Bash tricks and only keep one, I’d would keep — hands down — the CTRL-R trick [back]