/Seven Surprising Bash Variables

Seven Surprising Bash Variables

Continuing in the series of posts about lesser-known bash features, here I take you through seven variables that bash makes available that you may not have known about.

1) PROMPT_COMMAND

You might already know that you can manipulate your prompt to show all sorts of useful information, but what fewer people know is that you can run a shell command every time your prompt is displayed.

In fact many sophisticated prompt manipulators use this variable to run the commands required to gather the information to display on the prompt.

Try running this in a fresh shell to see what happens to your session:

$ PROMPT_COMMAND='echo -n "writing the prompt at " && date'

2) HISTTIMEFORMAT

If you run history in your terminal you should get a list of commands previous run by your account.

$ HISTTIMEFORMAT='I ran this at: %d/%m/%y %T '

Once this variable is set, new history entries record the time along with the command, so your history output can look like this:

1871  I ran this at: 01/05/19 13:38:07 cat /etc/resolv.conf
1872  I ran this at: 01/05/19 13:38:19 curl bbc.co.uk
1873  I ran this at: 01/05/19 13:38:41 sudo vi /etc/resolv.conf
1874  I ran this at: 01/05/19 13:39:18 curl -vvv bbc.co.uk
1876  I ran this at: 01/05/19 13:39:25 sudo su -

The formatting symbols are as per the symbols found in man date.

3) CDPATH

If you’re all about saving time at the command line, then you can use this variable to change directories as easily as you can call commands.

As with the PATH variable, the CDPATH variable is a colon-separated list of paths. When you run a cd command with a relative path (ie one without a leading slash), by default the shell looks in your local folder for matching names. CDPATH will look in the paths you give it for the directory you want to change to.

If you set CDPATH up like this:

$ CDPATH=/:/lib

Then typing in:

$ cd /home
$ cd tmp

will always take you to /tmp no matter where you are.

Watch out, though, as if you don’t put the local (.) folder in the list, then you won’t be able to create any other tmp folder and move to it as you normally would:

$ cd /home
$ mkdir tmp
$ cd tmp
$ pwd
/tmp

Oops!

This is similar to the problems seen when the dot folder is not included in the more familiar PATH variable.

For example, mine is set with a leading .:

CDPATH=.:/space:/etc:/var/lib:/usr/share:/opt

This is based on some of the contents of my book Learn Bash the Hard Way, available at $6.99.

hero

4) SHLVL

Do you ever find yourself wondering whether typing exit will take you out of your current bash shell and into another ‘parent’ shell, or just close the terminal window entirely?

This variable tracks how deeply nested you are in the bash shell. If you create a fresh terminal you should see that it’s set to 1:

$ echo $SHLVL
1

Then, if you trigger another shell process, the number increments:

$ bash
$ echo $SHLVL
2

This can be very useful in scripts where you’re not sure whether you should exit or not, or keeping track of where you are in a nest of scripts.

5) LINENO

Also useful for introspection and debugging is the LINENO variable, which reports the number of commands that have been run in the session so far:

$ bash
$ echo $LINENO
1
$ echo $LINENO
2

This is most often used in debugging scripts. By inserting lines like: echo DEBUG:$LINENO you can quickly determine where in the script you are (or are not) getting to.

6) REPLY

If, like me, you routinely write code like this:

$ read input
echo do something with $input

then it may come as a surprise that you don’t need to bother with creating a variable at all:

$ read
echo do something with $REPLY

does exactly the same thing.

7) TMOUT

If you’re worried about staying on production servers for too long for security purposes, or worried that you’ll absent-mindedly run something harmful on the wrong terminal, then setting this variable can act as a protective factor.

If nothing is typed in for the number of seconds this is set to, then the shell will exit.

So this is an alternative to running sleep 1 && exit:

$ TMOUT=1

If you like this, you might like one of my books:
Learn Bash the Hard Way

Learn Git the Hard Way
Learn Terraform the Hard Way

LearnGitBashandTerraformtheHardWay

Get 39% off Docker in Practice with the code: 39miell2