Some basic shell tips

In the following we will walk through some random (Bash) shell tips. Think of it as a 101 of shell interactions; some might be useful refreshers others may in fact be new to you— they certainly have been to me, despite using Bash for some 20 years.

File descriptors: stdin, stdout, stderr

So, the Bash shell has three default file descriptors (FD) for each process:

  • 0 aka stdin
  • 1 aka stdout
  • 2 aka stderr

Assuming the terminal is /dev/tty0 then all three point to it on process launch and here’s what you can with those FDs, for example:

# redirect stdout to some file:
command 1> file 

# redirect stderr to some file:
command 2> file 

# redirect both stdout and stderr
command &> file  

# same as previous, more idiomatic (?):
command >file 2>&1 

# discard output:
command > /dev/null 

# redirect stdin:
command < file 

# pipe commands, connect stdout of one with stdin of next:
cmd1 | cmd2 | cmd3

# show exit codes of each piped command:
echo ${PIPESTATUS[@]} 

You can learn more about FD and redirects from the excellent post Bash One-Liners Explained, Part III: All about redirections.

History and searching

First off, here’s how I have my history configured in .bashrc (note that I’m using tmux, which I can strongly recommend):

# history control, see also http://mywiki.wooledge.org/BashFAQ/088
export HISTIGNORE="pwd:ls:l:ps:top:more:less💿bc:cdf:cdr🧉clear:history:screen"
export HISTTIMEFORMAT='%FT%T '
export HISTSIZE=3000

# avoid duplicates:
export HISTCONTROL=ignoredups:erasedups
shopt -s histappend

# after each command, save and reload history:
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Now, you can do a simple (reverse) search using CTRL+R. Once you’ve found something, use the right key to select it. Like what you see there? Then hit ENTER to execute or edit the line (tip: use CTRL+W to delete entire words).

If you changed your mind or have another idea, you can use CTRL+G to cancel search.

Or, if the first item was not what you where looking for (say, you have a couple of commands all starting with git in your history) and you want to cycle through the matches, hit CTRL+R again until you’re satisfied … or bored.

Related: to repeat the previous command you can use !!. And you can even replace bits. For example:

# let's create a dummy directory and file:
$ mkdir foo && cd $_ && touch bar

# first we just list entries:
$ ls -a
.       ..      bar

# now we want to execute same but then
# add some more:
$ !!:s/-a/| wc -c
ls | wc -c
       4

One last one, mainly useful for giving a demo or the like: rather than typing clear and hitting ENTER like an imbecile, simply hit CTRL+L and your friends will believe you know Ken Thompson from the gym.

And this is how you handle the Bash shell basics. Got a better way? Let us know!