bash-isms i wish i knew earlier

I’ve been using bash for far too long (> 10 years now), and I was reminded the other day (after helping a colleague with some coding) of some of the random tricks that you pick up over time. I’ve put them into a (almost completely wrong) timeline. Are there any other common idioms that I’m forgetting to put in here?

Day 1:

“Oh man, look at that, I can hit up-arrow and repeat the previous command!”

You’re too excited by the novelty that you don’t pay attention to the fact it’s slower then retyping the old command.

Day 30:

After again hitting up-arrow 30+times to find an old command, you accidentally come upon reverse i-search (


) and realize what it means.

You start using quick substitution:

echo foo

And are feeling pretty much like a master.

Month 6:

HERE documents are now completely under your control, and you have started writing scripts to try to automate everything, even operations that you know you’ll only have to do once.

You spend at least one entire day fiddling with themes, in the name of “productivity”.

Year 1:

You’re feeling more confident, and moreover, the reckless abandon of your Bash youth seems to have passed. After a brief spell with the vi key bindings, you’re back to the emacs bindings, but feeling invigorated by your exploration. You realize that there is a separation between inputrc and bashrc, but you don’t really have time to investigate further. After all, you just added

set completion-query-items 10000
set completion-ignore-case On

to your


and are far too excited about the idea of never being asked:

Display all 3425 possibilities? (y or n)?

every again.

Year 2:

export HISTSIZE=1000000
export HISTFILESIZE=1000000
shopt -s histappend

How could it have taken you so long to search for this? No longer will having multiple terminals open cause you to lose your hard earned history. You anticipate the point in time where you will have accumulated so many commands in your history file that you will never have to type a new one.

Year 3:

You dabble with ZSH after seeing a friends super colorful console. You give up after you realize that zsh is missing most of the awesome TAB-completions you are by now accustomed to. By accident, you try tab-completing an scp command and are floored by the fact it’s actually based on the remote filesystem. You start trying to write your own completion scripts, but realize these are things better left to experts. It is slowly dawning on you that you are not an expert.

You’ve also become more confident in your escapes – you feel not the slightest bit scared about using arithmetic now:


And you use the subshell escape

result=$(echo foo)

to differentiate yourself from those silly backtick users who don’t know what they’re missing:

ROOT=$(dirname $(dirname $(readlink -f $0)))

Year 5:

You accidentally hit


again, but this time you noticed the magic keystrokes that got you here. An


window for modifying the command line? How cool is this? Now your Awk scripts will become even more powerful (and ever more incomprehensible).

Year 10:

Your scripts have started to become Zen-like koans of existential beauty. Your full knowledge of the power of

trap EXIT

allows you to impress your neighbors, whose adulation you accept with a wry smile. You know when to


and when to

  • you use force only when required.

You have come to the realization that you are just a beginner, and have so much more to learn.

11 Replies to “bash-isms i wish i knew earlier”

  1. One feature of Bash that I use all the time is the history substitution. Many are familiar with the following idom:

    $ some-root-operation
    Hey, you’re not root! Exiting!
    $ sudo !!

    Since I often like to dig into scripts, I use this in combination with which and $(…):

    $ which cpanm # make sure I actually have it
    $ vim $(!!) # or, if you’re further down, vim $(!which)

    !!, however, is scratching the surface:

    # work, work, work…
    $ git add -p # add work
    $ git commit
    $ git push origin master:master # I like to be explicit!
    # more working…
    $ git add -p
    $ git commit
    $ !?push # expands to last command containing ‘push’; works like Ctrl-R

    And !$ is the history substitution I use the most:

    $ mkdir /tmp/foo
    $ cd !$ # expands to ‘cd /tmp/foo’
    $ vim
    $ chmod 755 !$

    I even overwrite some common commands so they work better with this idiom:

    $ cd ~/projects
    $ git clone hoelzro:my-project
    $ cd !$ # expands to “cd hoelzro:my-project”; I use a custom ‘cd’ to handle this situation


  2. My main trick is:
    a() { alias $1=cd $PWD; }

    Much more powerful than pushdir. cd somewhere and type:
    a 1

    Later just type 1 and you cd back to that location.

  3. I too use this with dirname, when I want to descend into the directory that contains some file.
    $ cat /very/long/path/where/some/related/files/exists/myfile
    $ cd `dirname !$`

    A related trick I like is substitution with !!
    $ python foo bar foo baz
    $ !!:s/foo/quux
    python quux bar foo bar

    essentially the same as ^foo^quux

    It’s more useful with /g though
    $ python foo bar foo baz
    $ !!:s/foo/quux/g
    python quux bar quux bar

  4. one that i like is arrays/lists

    $ mkdir {app, bin, lib, src, src/{headers, vendor},etc}

    which in this example runs mkdir for each of the list entries

    mkdir app
    mkdir bin
    mkdir lib
    mkdir src
    mkdir src/headers
    mkdir src/vendor
    mkdir etc

Leave a Reply

Your email address will not be published. Required fields are marked *