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 (CTRL+R) and realize what it means.
You start using quick substitution:
echo foo
^foo^bar
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 .inputrc 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:
MYPORT=$((PORTBASE + 1))
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 CTRL+X CTRL+E again, but this time you noticed the magic keystrokes that got you here. An $EDITOR 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 CTRL-\ (SIGQUIT) and when to CTRL-C (SIGINT) – 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.
show off!
but thanks for the tips.
Year x (mine is 9):
You read that there is a built-in command called disown. You feel as newbie as day 1.
Good one – I love disown!
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 myfile.pl
$ 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
-Rob
Rob,
Instead of a
$ cd !$
You can also do a alt period
$ cd .
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.
@Joe Neat trick, thanks!
Or you could use ‘cd -’
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 myscript.py foo bar foo baz
$ !!:s/foo/quux
python myscript.py quux bar foo bar
essentially the same as ^foo^quux
It’s more useful with /g though
$ python myscript.py foo bar foo baz
$ !!:s/foo/quux/g
python myscript.py quux bar quux bar
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
Pingback: How to Make Your Life Easier with Bash Shell