Fundamentals 26 min read

When to Use exec, source, or fork in Bash? A Practical Guide

This article explains the differences between exec, source, and fork in Bash, covering process creation, environment variable inheritance, command groups, variable substitution, positional parameters, logical operators, and provides example scripts to illustrate each concept for effective shell scripting.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
When to Use exec, source, or fork in Bash? A Practical Guide

Question 6: What is the difference between exec and source?

Question 7: What is the difference between ( ) and { }?

Question 8: What is the difference between (()), ( ), and ${ }?

Question 9: What is the difference between @ and *?

Question 10: What is the difference between && and ||?

This article is compiled from a 2003 CU post that collected useful Linux fundamentals.

Question 6: What is the difference between exec and source?

Consider the example where a script changes directory with cd /etc/aa/bb/cc but the change does not persist after the script finishes. This is because each script runs in a subshell, a child process created by the parent shell. When the child process ends, its environment (including the working directory) is not inherited back by the parent.

Environment variables are inherited only from parent to child, not the other way around. Therefore, a script executed via a subshell cannot modify the parent shell's environment.

The source command runs a script in the current shell without creating a subshell, so any changes to variables or the working directory affect the current environment.

Example: ./my.script can be changed to: source ./my.script or simply: ../my.script Using exec replaces the current process with the new command, terminating the original process. This is the main difference from source and a subshell.

Example scripts to illustrate the three behaviors:

#!/bin/bash
A=B
export A
echo "PID for 1.sh before exec/source/fork:$$"
case $1 in
  exec)
    echo "using exec…"
    exec ./2.sh;;
  source)
    echo "using source…"
    source ./2.sh;;
  *)
    echo "using fork by default…"
    ./2.sh;;
esac
echo "PID for 1.sh after exec/source/fork:$$"
#!/bin/bash
echo "PID for 2.sh: $$"
echo "2.sh get A=$A from 1.sh"
A=C
export A
echo "2.sh: A is $A"

Run the scripts with ./1.sh fork, ./1.sh source, and ./1.sh exec to observe the different outputs.

Question 7: What is the difference between ( ) and { }?

( ) creates a subshell for the command group, while { } executes the commands in the current shell. Use ( ) when you want temporary changes that should not affect the parent shell, and { } when you want changes to persist.

In Bash, a function can be defined using either syntax:

function function_name {
  command1
  command2
}
function_name() {
  command1
  command2
}

Functions behave like scripts but run in the current shell, allowing reuse of code without spawning new processes.

Question 8: What is the difference between (()), ( ), and ${ }?

$( )

and backticks perform command substitution, inserting the output of a command into another command line. ${ } is used for variable substitution and provides additional features such as default values, substring removal, and length calculation.

Examples of variable manipulation with ${ }:

file=/dir1/dir2/dir3/my.file.txt
${file#*/}   # dir1/dir2/dir3/my.file.txt
${file##*/}  # my.file.txt
${file%/*}   # /dir1/dir2/dir3
${#file}    # 27 (length)

Arrays can be defined and accessed:

A=(a b c def)
${A[@]}   # a b c def
${A[0]}   # a
${#A[@]}  # 4

Arithmetic expansion uses $(( )) for integer calculations:

a=5;b=7;c=2
echo $((a+b*c))   # 19
echo $(((a+b)/c)) # 6

Question 9: What is the difference between $@ and $*?

Both represent all positional parameters, but when quoted they behave differently. "$@" expands to each parameter as a separate word, preserving spaces, while "$*" expands to a single word with all parameters concatenated.

Example:

#!/bin/bash
echo "the number of parameters in \"$@\" is "$(my_fun "$@")
echo "the number of parameters in \"$*\" is "$(my_fun "$*")

Question 10: What is the difference between && and ||?

These logical operators chain commands based on return values. command1 && command2 runs command2 only if command1 succeeds (return value 0). command1 || command2 runs command2 only if command1 fails (non‑zero return value).

Example:

A=123
[ -n "$A" ] && echo "yes! it's true."
unset A
[ -n "$A" ] || echo "no, it's NOT true."

These concepts are essential for writing robust Bash scripts that react to success or failure of commands.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

forkexecEnvironment Variablescommand substitution_source
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.