1. Overview

We know that the .bashrc file will be executed when the Bash shell starts interactively.

It initializes an interactive shell session. Usually, the .bashrc file is an excellent place to put aliases and predefined functions.

In this quick tutorial, let’s see how to include additional files in the .bashrc file.

2. Introduction to the Problem

Sometimes, to make it easier to maintain, we may want to save some Bash settings or functions in separate files and include them in the .bashrc.

However, this will fail if we don’t include the file correctly. Let’s see an example to understand the problem quickly.

2.1. The Additional Script File

Let’s say we have a script file additional_script.sh:

$ cat /home/kent/bin/additional_script.sh
#!/bin/bash
echo "Loading the additional_script.sh file"
CONF_LOADED=true

alias lecho="echo 'Linux Rocks!'"

#function to print local times of 3 citites
function world_clock {
  echo "New York Time:" $(TZ="America/New_York" date +"%F %H:%M:%S")
  echo "Paris Time   :" $(TZ="Europe/Paris" date +"%F %H:%M:%S")
  echo "HongKong Time:" $(TZ="Asia/Hong_Kong" date +"%F %H:%M:%S")
}
echo "additional_script.sh loaded."

In the additional_script.sh file, we’ve defined a variable, an alias, and a function.

2.2. Trying to Include additional_script.sh in the $HOME/.bashrc File

Now, let’s make our additional_script.sh file executable and append a line to the $HOME/.bashrc file:

$ tail -1 ~/.bashrc
/home/kent/bin/additional_script.sh

Next, let’s start a new Bash shell and check if Bash has included the additional_script.sh file:

$ bash
Loading the additional_script.sh file
additional_script.sh loaded.

We’ve seen the log message. It seems that Bash has found and included the file. Great!

Let’s do some tests to verify if the variable, the alias, and the function we defined work as expected:

$ echo $CONF_LOADED

$ lecho
bash: lecho: command not found
$ world_clock
bash: world_clock: command not found

As the output above shows, none of them is working.

Next, let’s figure out why this is happening and how to solve the problem.

3. Including additional_script.sh in the $HOME/.bashrc File Properly

We’ve tried to include the additional_script.sh file in .bashrc by appending the script file path to the .bashrc file. But it didn’t work as expected.

It’s a pretty common pitfall when we call or include a script file from another one. So next, let’s figure out why it happens.

3.1. The Difference Between Executing a Script and Sourcing a Script

When Bash sees the filename /home/kent/bin/additional_script.sh, it’ll execute the script.

Further, when Bash executes a script, it’ll run it in a new shell process. This new shell process is a child process of the current shell. Therefore, we can also call this new shell “subshell.”

If the executed script produces output, the output will be copied back to the current shell. That’s why we’ve seen the log messages.

However, if the script leads to any changes to the environment, such as changing variables or declaring new aliases or functions, the changes will only take effect in the subshell.

After Bash has executed the script, the subshell process will be terminated. So, naturally, the changes to the subshell will be lost as well. This explains why the variable, the new alias, and the function didn’t work in our current shell.

What we would like to achieve is to apply these changes to the environment to the current shell. Thus, the source command is exactly what we’re looking for.

Simply put, unlike executing a script, sourcing a script will run the commands in the script in the current shell. Therefore, all changes to the environment will take effect in the current shell.

3.2. Using the source Command

We can use either of two forms to source a script:

source SCRIPT_FILE
. SCRIPT_FILE

Both forms work exactly the same. In this tutorial, we’ll go with the first one.

Now, let’s fix the problem in the $HOME/.bashrc file by using the source command:

$ tail -1 ~/.bashrc
source /home/kent/bin/additional_script.sh

Next, let’s start a new Bash shell and check if the script file is correctly included:

$ bash
Loading the additional_script.sh file
additional_script.sh loaded.

$ echo $CONF_LOADED
true

$ lecho
Linux Rocks!

$ world_clock
New York Time: 2021-09-26 19:07:22
Paris Time   : 2021-09-27 01:07:22
HongKong Time: 2021-09-26 07:07:22

This time, as we can see, not only have the log messages been printed, the CONF_LOADED variable, the lecho alias, and the world_clock function have been loaded to the current shell.

So, we’ve solved the problem.

4. Error Handling and Including Multiple Files

So far, we’ve learned to use the source command to include an additional script in .bashrc.

It’s a good practice to check if the file exists before we source it. Therefore, we can improve the source command in this way:

if [ -f /home/kent/bin/additional_script.sh ]; 
then
    source /home/kent/bin/additional_script.sh
else
    echo "File Not Found: /home/kent/bin/additional_script.sh"
    # ... other error handlings
fi

Also, we may want to include multiple files in .bashrc.  Instead of duplicating the “if” block many times, we can use a loop and an array to check and include them:

files_to_source=("/path/to/script1" "/path/to/script2")

for file_to_source in ${files_to_source[@]}
do 
    if [ -f "$file_to_source" ];
    then
        source "$file_to_source"
        echo "Loaded $file_to_source"
    else
        echo "File Not Found: $file_to_source"
        # ... additional error handlings
    fi
done

5. Conclusion

In this tutorial, we’ve discussed the difference between executing a script and sourcing a script in Bash.

Also, we’ve addressed how to include additional scripts in the .bashrc file through examples.


« 上一篇: POSIX指南