Some bash options are well known, and well-used. For example, many people put
set -o xtrace
at the top of their scripts to debug them,
set -o errexit
to exit on error, or
set -o errunset
to exit if a variable is referenced but not set.
But there are many other options you can set. Many of them can seem confusing if you read the man page, so I’ve collected some of the ones I think are more useful here and explained them further.
NOTE
If you are using a Mac, then you may be running
an older version of bash (3.x rather than 4.x)
that does not have all these
options available. If so, see here or here.
set
vs shopt
?
There are two ways to set bash options from within scripts or on the command line. You can use the set
builtin command, or the shopt
builtin command. They both manipulate the behaviour of the shell, and differ in their lineage. The set
options are inherited, or borrowed, from other shells’ options, while the shopt
ones were originated in bash.
If you want to see how your current settings look, then run:
$ set -o
$ shopt
To switch on a setting using set, you can use the long version, or a shorter flag that is equivalent. For example:
$ set -o errunset
$ set -e
both have the same effect.
To switch off a setting using set, you use +
instead of -
:
$ set +e
For a long time I couldn’t remember which way round it goes, as the logic of (-
= on), and (+
= off) seems wrong to me.
To switch on and off a shopt
setting, you use the (more logical)-s
(set) and -u
(unset) flags:
$ shopt -s cdspell # <= on
$ shopt -u cdspell # <= off
Changing Directories
There are a few options that can help dealing with directories.
1. cdspell
If you set this up, then bash will work around your mis-spellings and go to the folder you were going for anyway.
$ shopt -s cdspell
$ mkdir abcdefg
$ cd abcdeg
abcdefg
$ cd ..
I’ve used this for years, and very occasionally (maybe once a year) it will make a decision that surprises me. But it probably proves useful at least once a day.
2. autocd
If the inefficiency of typing cd
is something you can’t bear, then you can set this option to move to folder if the command doesn’t exist.
$ shopt -s autocd
$ abcdefg
$ cd ..
You can also use it in conjunction with autocompletion to quickly hop around:
$ ./abc[TAB][RETURN]
cd -- ./abcdefg
Just don’t call a folder ‘rm -rf *
‘ (yes, you can, by the way).
3. direxpand
This is a neat option that gets the shell to perform any expansions of variables, tildes and the like right there for you in the command line if you tab to complete:
$ shopt -s direxpand
$ ./[TAB] # is replaced by...
$ /full/path/to/current_working_folder
$ ~/[TAB] # is replaced by...
$ /full/path/to/home/folder
$ $HOME/[TAB] # is replaced by
$ /full/path/to/home/folder
A Clean Exit
4. checkjobs
This option stops the shell session from exiting if there are any jobs running in the background that haven’t finished yet.
Instead, the unfinished jobs are listed for you. If you still want to exit, you can if you enter exit
immediately afterwards again.
$ shopt -s checkjobs
$ echo $$
68125 # <= Process ID of the shell
$ sleep 999 &
$ exit
There are running jobs.
[1]+ Running sleep 999 &
$ echo $$
68125 # <= Process ID of the shell is the same
$ exit
There are running jobs.
[1]+ Running sleep 999 &
$ exit
$ echo $$
$ 59316 # <= Process ID has changed this time
Globbing Superpowers
5. globstar
This option gives you globbing superpowers! If you type:
$ shopt -s globstar
$ ls **
then the shell will output recursively all folders and subfolders.
Combined with direxpand
, you can quickly page through all the files and subfolders beneath you:
$ shopt -s direxpand
$ ls **[TAB][TAB]
Display all 2033 possibilities? (y or n)
6. extglob
This option gives your globbing powers more commonly associated with full-on regular expressions. Occasionally, this is very useful, as it allows you to do nifty things like this:
$ shopt -s extglob
$ touch afile bfile cfile
$ ls
afile bfile cfile
$ ls ?(a*|b*)
afile bfile
$ ls !(a*|b*)
cfile
where the patterns are placed in parentheses, separated by pipes, and the operators available are:
? = match zero or one occurences of the patterns given
! = match anything that doesn't match any patterns given
* = zero or more occurences
+ = one or more occurrences
@ = exactly one occurence
Accident-prone?
7. histverify
If you’re accident prone, then using the history shortcuts like !!
and !$
can be scary, especially when you’re just learning them.
The histverify
option allows you to see how bash interprets the command before it actually gets run:
$ shopt -s histverify
$ echo !$ # <= On hitting return, command is not run
$ echo histverify # <= Command is redisplayed ready to run
histverify # <= command gets run
This is based on some of the contents of my book Learn Bash the Hard Way, available at $6.99.
8. Noclobber
Again, if you’re accident-prone, you might want to set this one up.
Clobbering is the act of overwriting a file that already exists with the redirect operator (>
). This can be disastrous if you’ve not got the file backed up anywhere else.
Using set -C
prevents this from happening when you use the redirect operator. If you are sure you want to clobber, you can override with the >|
operator instead:
$ touch afile
$ set -C
$ echo something > afile
-bash: afile: cannot overwrite existing file
$ echo something >| afile
$
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

Here’s another useful one for the Changing Directories sections:
export CDPATH=.:/some/frequently/visited/path:/tmp:
Now, you can magically cd into any of the directories in the CDPATH variable without having to specify the full path ! This variable is also honored when showing up matches with tab completion (if you use bash-completion).
For example, if you have a directory ‘~/src’ where all your projects live, add CDPATH=.:${HOME}/src to your bashrc and then you can simply do a ‘cd my_project’ to cd into it !
Remember tho’ to add the ‘.’ as the first component …think about it :-)
You’ve anticipated my ‘obscure but useful shell variables’ post…