Bash configuration scripts
When bash starts, it runs one or more scripts in order to setup the user's environment variables, any aliases, and what programs to run at startup. This post explains what scripts are involved, when they're executed, and what to put in them.
What environment variables would you find in them?
Environment variables such as PATH get modified in ~/.profile
. The PS1 environment variable gets set by the script /etc/bash.bashrc
in order to make your command prompt look the way it does.
You can add your own into ~/.bashrc
as required. For example, you may be running some software that has different behaviour when an environment variable is set to a specific value. Such environment variables will be explained in the man page or info page for that software.
Note that in these bash configuration scripts, lines that are preceded by a #
are commented out, so have no effect.
Scripts run at login
When bash is invoked, it runs /etc/profile
if that file exists. Next, it looks for these files (in this order) ~/.bash_profile
, ~/.bash_login
, and ~/.profile
.
The first one that is found gets executed (any others are ignored). In the case of Ubuntu, ~/.profile
is found and executed. (All of ~/.bash_profile
, ~/.bash_login
, and ~/.profile
are ignored if --noprofile
is used as an option to the underlying bash call).
So for example, if you login with a virtual console, or if you change to another user:
sudo su anotherusername
or if you run:
bash --login
or if you login to a machine with ssh:
ssh user@machine
You'll be invoking ~/.profile.
Note that ~/.profile
(or if not there, one of ~/.bash_profile
or ~/.bash_login
) normally contains relevant commands to run another script called ~/.bashrc
(if said file exists):
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
Scripts run when non login shell started
When you start bash but no login was required, the script /etc/bash.bashrc
is run along with the script ~/.bashrc
(if they exist). For example, if you're logged into your desktop and open a virtual terminal (no login required) the .bashrc
scripts get invoked. (These .bashrc
scripts will be ignored if the underlying call to bash uses the option --norc
). For more info, see the INVOCATION section of the bash manpage.
What's normally put in ~/.profile
and ~/.bashrc
?
In ~/.profile
(or one of it's alternatives: ~/.bash_profile
, etc ...) you would run commands that you want to run once when a user logs in but not every time they open a terminal.
In .bashrc
, one normally puts commands and configurations that you wish to make effective for a bash session. For example, customised tweaks and things that make it easier for you to use BASH as you want, such as aliases and functions. Aliases can be considered as a shorthand nickname for a specific command (plus its arguments if required).
Some simple examples can be seen in the default .bashrc
file in your home directory.
Take a look using the less
command:
less ~/.bashrc
If you scroll down through the file, you'll see something like the aliases shown below:
These are pretty straight forward. All they do is add color to the grep
/fgrep
/egrep
commands and add a few handy "ls" shortcuts to save you from entering all those options. (Note that the word alias is highlighted as a result of a search in the less command).
A few other simple examples are:
alias untar='tar xzvf'
Which would allow you to simply call untar
rather than having to remember the arguments xzvf
when calling tar.
Note that if you make changes to your .bashrc
script, you'll not see the changes take effect until you start a new shell or run:
source ~/.bashrc
This will load the changes to your current bash session.
The below example is really handy:
alias update='sudo apt-get update'
and this next example adds a safety measure to the rm
command:
alias rm="rm -i"
It prompts you to confirm you want the deletion to proceed.
Functions can be defined to do more complex tasks. The format is simple, and you just need to add them to your .bashrc
file just like an alias:
myFunc()
{
# commands
}
Here is an example of a function to find a file under you current directory location:
myfind() {
find ./ -name $1 -print
}
To use it, just run:
myfind someFile.txt
(remember to source ~/.bashrc
if you want to load the change to your current shell... subsequent shells will get it by default).
For a case-insensitive version, you could use:
imyind() {
find ./ -iname $1 -print
}
So running your new "command" will not require that you know the exact case:
imyfind somefile.txt
That is searching for somefile.txt will find someFile.txt.
There no need to get too in-depth with regard to bash scripting to understand how these work once you know that $1
is a variable to the function which is supplied as the argument to your command when you run it.
That is the filename you're looking for gets shoved in to the command, effectively replacing the $1
.
If your function requires more argument variables, just use $2
, $3
, $4
etc