Bash Setup
The command line can be a powerful tool for smaller and bigger tasks. If you want to get a taste, have a look here.
However, the amount of fun that you have while working with the command line crucially depends on how your command line is set up.
Personally, I am a big fan of zsh
and this repo to customize it.
At some point, I might write about my own setup.
On clusters, however, there is not always a choice and the default shell on most Linux distributions is bash anyway. So, how do we make working with bash as much fun as possible?
Overview
There are two main files to change the way that the bash command line reacts: .inputrc
and .bashrc
.
Both files live in your home directory ($HOME).
.inputrc
changes the way that the GNU readline library reacts.
This file alters way more than just the behavior of your bash.
All programs that use the readline library will react differently.
The second option is the .bashrc
.
This is the user’s, aka your, configuration file for the bash.
Here, you can define useful shorthands and functions to change the bash interacts with you.
An example .inputrc
Without further ado, let’s get started with the .inputrc
.
TL;DR
Use this file as your .inputrc to have smoother experience while using the command line. Lines 2 and 3 enable searching with partial input by using the up-arrow. It is a game changer.
1set bell-style none
2"\e[A": history-search-backward
3"\e[B": history-search-forward
4
5"\C-f": forward-word
6"\C-b": backward-word
7
8set show-all-if-ambiguous on
Line-by-Line explanation
Let’s go through the file line by line.
set bell-style none
This line configures the bell (audible or visible alert) behavior. Here, we set the bell style to “none,” meaning that no bell will be produced when a terminal bell character is received. After all, who wants a beeping computer."\e[A": history-search-backward
and"\e[B": history-search-forward
These two lines modify the search behavior of the readline library. The first line bindsUp
arrow (escape sequence\e[A
) to the actionhistory-search-backward
. In practice, that means that you can start typing a command, let’s saypython fo
and by pressing theUp
arrow, you get all commands from your bash history starting with those characters. In this case, it could bepython foo.py --abc 3 --def 9
. By pressingUp
again, you will get the next match.
In case you miss a match, we bind theDown
arrow (\e[B
) tohistory-search-forward
, i.e. searching in the other direction. For me, this was a big change in terms of working on the command line. No moreCtrl+r
all the time."\C-f": forward-word
and"\C-b": backward-word
This line binds the key combinationCtrl + f
to the action of moving the cursor forward by one word. In the same way,Ctrl + b
will move the cursor back one word. If you are inemacs
modealt + b
andalt + f
will do the same for you.set show-all-if-ambiguous on
This line sets the option enables the optionshow-all-if-ambiguous
. When this option is enabled,readline
will show all possible completions rather than ringing the bell if the tab key is pressed and there is more than one possible completion. As an example, imageine you have two filesabcd.txt
andabce.txt
. By typingls a<tab>
, you getls abc
. This is the common prefix. Now, the option kicks in since there is no common prefix anymore. If you press<tab>
again, you get
>ls abc
abcd.txt abce.txt
>ls abc
without the bell. I find that a very handy option.
An example .bashrc
There is not only the readline library, there is also the configuration of the bash directly
TL;DR
Here is an example .bashrc
, for a user that might be calle foo
.
In case you are working on a managed machine, please do NOT just substitute your .bashrc
.
Adding it to the end is much safer.
The most important thing about a .bashrc
: Define useful alias
commands and shortcuts is key.
1#
2# MORE STUFF
3#
4
5# Definition of environment variables
6export PEPS_PROJ=/data1/foo/data/project/peps/
7# Add an executable to the PATH variable
8export PATH=$PATH:/home/foo/projects/peps/tools
9
10# Define some alias commands
11
12## Related to SLRUM cluster operations
13alias squeuel='squeue --format="%.18i %.9P %.30j %.8u %.2t %.10M %.6D %R" -u foo'
14alias sinfot='sinfo -M all -N -o "%25P %16N %16T %16C %10z %.10e/%10m %10g %b"'
15
16## Related to git
17alias gd='git diff'
18alias gst='git status'
19alias gco='git checkout'
20alias gc='git commit'
21alias ga='git add'
22
23## Related to general navigation
24alias ll='ls -l'
25alias l='ls -l'
26alias ..='cd ..'
27alias ...='cd ../..'
28
29# Adapt the prompt to something that I like
30export PS1="\u@\h:\W> "
Section-by-Section explanation
Let’s have a look at the file section by section. Here, I will not explain every command, but rather the spirit of the sections. You will have to adapt the concrete commands anyway.
Definition of environment variables
Sometimes, it is handy to have some shortcuts for long directory names. Imagine you often have to change to a data directory or address files there. By defining an environment variable like$PEPS_PROJ
, you can make changing directory smoother.Adding folders to
$PATH
If you want to call a program without typing its full path or even./<name_of_program>
in the same folder, the program must be in your$PATH
. The bash reads your$PATH
variable and checks in all folders whether the name that you typed is in there. If so, it is considered as a command and will be executed as such. If you write custom tools for your project, it makes sense to place the containing folder in your$PATH
variable. In foo’s project, some of the tools can now be called from every directory of foo’s computer.
The idea of the command in line 8 is to append a directory to the existing path. The first part of the commandPATH=$PATH
assigns the variablePATH
to itself. Be careful with the spaces here. There are none. Bash is tricky with variable assignments. It only works without spaces.
In Linux, the colon (:
) character is used to separate directories from one another. By executingPATH=$PATH:<some_directory
,some_directory
is added to the back of thePATH
. It is crucial that we are appending here, since Linux traverses the directory inPATH
in order of appearance. Although you should never all a filels
, it gets much more annoying if that file ends up in yourPATH
before/usr/bin/ls
.alias
commands
The most important tool, in my opinion, to make life on the command line more enjoyable arealias
commands. Analias
command gives a new name to an otherwise longer command. For moving up in the directory tree, I prefer to type..
instead ofcd ..
. Thus, there is analias ..="cd .."
in my.bashrc
. Note that there are again no spaces around the = sign. As you can see, there is a whole plethora of alias commands concerninggit
, SLURM and movement commands. Pick your favorites and start adding some yourself to your own.bashrc.
Changing the prompt
The prompt is the beginning of each line in the shell that is displayed before you type a command. I like to know where I am, both in terms of computer (hostname) and directory. Thus, here is an explanation of my favorite (bash) prompt"\u@\h:\W> "
:\u
: Represents the username of the current user.\h
: Represents the hostname (the name of the computer) up to the first ‘.’.\W
: Represents the current working directory (only the last part of the full path, not the entire path). If you like the full path, you can use\w
. In words this looks like
<username>@<hostname>:<current_directory> >
If your user is called john
working on a machine named mycomputer
and his current working directory is Documents
, the prompt will read
john@mycomputer:Documents >
I hope that this post makes working with the command line more fun for you. Let me know about your favorite setups in the comments.