Linux

Learn Difference Between Sourcing and Forking in Bash

The main focus of this article is to clearly understand what happens when you run the script vs source the script in bash. First, we will clearly understand how the program is submitted when you call the script in different ways.

NOTE: creating the script with an extension doesn’t matter. Script will run fine even without extensions.

Basically, every script starts with a line called a shebang(#!). The Hash symbol in bash will be interpreted as comments but shebang has a special meaning. It tells bash to submit the program in whatever interpreter you mentioned in shebang.

Below are a sample program and I am specifying bash as my interpreter.

$ cat >> Hello_World.sh
#!/usr/bin/env bash
echo "Hello world"

$ chmod +x Hello_world.sh

Now to run the script, you can do it in two ways.

  • Use a relative path to call the script. Move to the directory where the script is present and run ./Hello_world.sh.
  • Use the absolute path to call the script. From anywhere in the file system type the full path to the script.
$ ./Hello_world.sh
$ pwd
$ /home/karthick/Hello_world
Run Shell Script
Run Shell Script

Now let’s see what happens when you try to submit your program without shebang. In absence of shebang, the program will be submitted to whatever current shell you are running with, In my case, it is Bash (/bin/bash).

Let me demonstrate an example. I am creating a python script without shebang and when I call the program, bash doesn’t know that it should submit this program to the python interpreter instead it will run the program in the current shell.

$ cat > run-py.py
echo $SHELL
print("Hello world")

$ chmod +x run-py.py
$ ./run-py.py
Wrong Interpreter in Script
Wrong Interpreter in Script

In this case, you can call the program by mentioning on which interpreter it should be submitted to or just add the shebang line which is always recommended.

# which python3
$(which python3) /home/karthick/run_py.py
Call Script With Interpreter
Call Script With Interpreter

Now that you know how to call the script, the next step would be to understand what happens when we call the script. When you invoke the script as shown in the above examples it will create a child process (forking) and the script will be submitted to the child process. I ran a sample script that will just run the following command and shows the script is submitted to a child process.

$ ps -ef --forest | grep -i bash
Forking
Forking

There can be multiple child processes as a part of the script and that depends on our code. It is to be noted that environmental variables created by subscript will be dropped once it gets finished. A child process can access variables created by the parent process by exporting them. But parent process cannot access the variables created by the child process.

Take a look at the below articles to understand more about how variables work and how to export the variables.

Sourcing the Script

Source” is a shell built-in command that reads the file passed as an argument to it and runs the code in the current shell environment. An appropriate use case that you use mostly is modifying your configuration in .bashrc or .bash_profile and reloading the changes using the source command.

$ type -a source
Shell Builtin Command
Shell Builtin Command

There are two syntactic ways to run the source command. You can choose anyone from two syntaxes and it is of personal choice.

$ source FILE_NAME [ARGUMENTS]
$ . FILE_NAME [ARGUMENTS]

Let me demonstrate how the source actually works. I am going to create two shell scripts. The first script (Module.sh) is going to hold some variables and functions. The second script (Main.sh) is going to print the variable and call the function.

File Module.sh.

#!/usr/bin/env bash

VAR1=$(echo "Welcome to $1")

function f1(){
  echo “Function f1 is called”
}

File Main.sh.

#!/usr/bin/env bash

echo $VAR1
f1
Sample Script Codes
Sample Script Codes

Set the execution permission for the script and call the main script “main.sh”. Now, this script will try to find the function f1 and variable VAR1 in the current shell environment and will fail with the command not found.

$ bash main.sh
Before Sourcing Script
Before Sourcing Script

Now let’s run the source command inside the script which will load the variable and functions into the current shell environment and that will be accessible by “main.sh”.

File Module.sh.

#!/usr/bin/env bash

VAR1=$(echo "Welcome to $1")

function f1(){
  echo "Function f1 is called"
}

File Main.sh.

#!/usr/bin/env bash

source module.sh Tecmint
echo $VAR1
f1
Sample Script Codes with Sourcing
Sample Script Codes with Sourcing

Now run the script again and see.

$ bash main.sh
After Sourcing Script
After Sourcing Script

The source is very useful in bash to follow the modular programming approach in creating our shell scripts. We can break our code into smaller modules and can be used in many programs. In these ways, we can follow the DRY (Don’t Repeat Yourself) principle.

That’s it for this article. We have briefly discussed the difference between sourcing and forking in bash. Go through the article and share your valuable feedback with us.

If You Appreciate What We Do Here On TecMint, You Should Consider:

TecMint is the fastest growing and most trusted community site for any kind of Linux Articles, Guides and Books on the web. Millions of people visit TecMint! to search or browse the thousands of published articles available FREELY to all.

If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.

Support Us

We are thankful for your never ending support.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to top button
%d bloggers like this:

Adblock Detected

Please consider supporting us by disabling your ad blocker