Linux Execute Shell Scripts – Source script.sh vs ./script.sh vs exec ./script.sh
In Linux executing ./my_script.sh and source my_script.sh are two different ways to run a shell script, but they behave differently in terms of scope and how the script is executed.
To show the different ways we can use in Linux to run a shell script, I will use the following simple Hello World script named my_script.sh.
#!/bin/bash # This is a simple Hello World script message="Hello, World!" echo $message cd /var/log
By the way the first line in the script above with #!/bin/bash is the so called shebang.
The shebang is used to tell the system which interpreter for the execution of the script should be used. When you have a Python script for example you need to add the following shebang on top of your script.
#!/usr/bin/python3
For a shell script we add the following shebang to tell the system to use the bash shell (Bourne-Again SHell) as interpreter for the execution of the script
#!/bin/bash
Below I will show the three different ways to run a shell script in detail.
./my_script.sh
When you use ./my_script.sh, the script is executed as a separate process (a new shell), and any changes made by the script, such as setting variables or changing the directory, are local to that subshell. Once the script finishes, any variables or environment changes in that subshell are lost, and your current shell remains unaffected.
The script needs to have execute permissions for this to work.
# chmod +x my_script.sh
Running my_script.sh above will set the variable message and change the directory inside the subshell to /var/log/, but those changes will not affect the current shell. After the script completes, you’ll still be in the original directory, and message will not be available in the current shell.
source my_script.sh
This runs the script in the current shell (i.e., in the same shell session) without creating a new subshell.
When you use source my_script.sh, the script is executed in the current shell, so any changes made by the script (like setting variables, changing directories, etc.) are persistent in the current session.
Unlike ./my_script.sh, source does not require execute permissions because the script is read and executed line by line within the current shell.
Running source my_script.sh will set message and change the directory in the current shell to /var/log/. So, after the script finishes, message will be available, and you will still be in /var/log in your current session.
exec ./my_script.sh
In Linux, the command exec ./my_script.sh replaces the current shell process with the process of the script being executed. The current shell will be terminated. This is different from simply running ./my_script.sh, which runs the script in a subshell.
When you use exec ./my_script.sh, the shell itself is replaced by the script, and the shell does not return after the script finishes because it no longer exists. The exec command in Linux replaces the current shell process with the script process, so the script effectively “becomes” the shell.
So when using exec in PuTTY below, after pressing enter PuTTY will be terminated because the current shell process will be terminated.
To better visualize this I will use the vSphere console below. After executing exec ./my_script.sh the current shell session will be terminated.
Links
What is a Subshell?
https://bash.cyberciti.biz/guide/What_is_a_Subshell%3FBash (Unix shell)
https://en.wikipedia.org/wiki/Bash_(Unix_shell)Shebang (Unix)
https://en.wikipedia.org/wiki/Shebang_(Unix)