Executing Shell Scripts from Within Other Scripts

Executing Shell Scripts from Within Other Scripts

A common task in shell scripting is to execute one script from within another. This allows you to modularize your code, reuse functionality, and build complex workflows. There are several ways to achieve this, each with its own implications for how the scripts interact with each other and the parent shell environment. This tutorial will cover the most common methods, explaining their differences and use cases.

Methods for Script Execution

Here are the primary ways to call one shell script from another:

  1. Direct Execution with Path: This is the simplest approach. If the script you want to execute has execute permissions (using chmod +x script.sh), and is either in your PATH environment variable or you provide its full or relative path, you can execute it directly:

    #!/bin/bash
    echo "Starting main script..."
    ./another_script.sh  # Assuming another_script.sh is in the same directory
    echo "Main script continues..."
    

    This method launches another_script.sh as a separate process. Any variables or functions defined within another_script.sh will not be accessible in the calling script. The scripts operate independently.

  2. source Command (or .): The source command (and its equivalent, the dot .) executes the contents of the specified script within the current shell process. This is a crucial difference from direct execution.

    #!/bin/bash
    echo "Starting main script..."
    source ./another_script.sh  # Or: . ./another_script.sh
    echo "Main script continues..."
    

    Because the script is executed in the same process, any variables, functions, or aliases defined within another_script.sh will be available in the calling script. This is useful for setting up environment variables or defining functions that you want to use throughout your workflow.

    Important Considerations with source:

    • If another_script.sh contains an exit command, it will also terminate the calling script.
    • Be mindful of variable name collisions. If both scripts define variables with the same name, the value from the sourced script will overwrite the value in the calling script.
  3. bash Command: You can also execute a script using the bash command:

    #!/bin/bash
    echo "Starting main script..."
    bash ./another_script.sh
    echo "Main script continues..."
    

    This is similar to direct execution. another_script.sh is launched as a separate process, and variables or functions defined within it are not accessible in the calling script.

  4. Using Subshells with exec: The exec command replaces the current shell process with the specified command. To avoid completely replacing your main script’s process, you can execute exec within a subshell, created using parentheses:

    #!/bin/bash
    echo "Starting main script..."
    ( exec ./another_script.sh )
    echo "Main script continues..."
    

    This effectively runs another_script.sh in a separate process but contained within the current shell environment.

Choosing the Right Method

The best method depends on your specific needs:

  • Independent Processes: If you want to run a script as a separate process without affecting the calling script’s environment, use direct execution with the path or the bash command.
  • Sharing Environment: If you need to share variables and functions between scripts, use the source command (or .).
  • Controlled Execution: Use subshells with exec when you need to run a script within a controlled execution context, minimizing the risk of unintended side effects.

Example

Let’s illustrate with a simple example. Assume we have two scripts: script1.sh and script2.sh.

script1.sh:

#!/bin/bash
echo "Starting script1..."
my_variable="Hello from script1"
source script2.sh  # Use source to share variables
echo "script1 continues: my_variable = $my_variable"

script2.sh:

#!/bin/bash
echo "Running script2..."
my_variable="Hello from script2"

If you run script1.sh, the output will be:

Starting script1...
Running script2...
script1 continues: my_variable = Hello from script2

Notice how the value of my_variable in script1.sh was overwritten by the value defined in script2.sh because we used the source command. If we had used ./script2.sh, the value of my_variable in script1.sh would have remained "Hello from script1".

Leave a Reply

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