Friday, 6 February 2026

sourcing a script inside another script

Lets' create a shell script with a simple function to log messages , this shell script will be sourced from other shell script .


[root@oel01db Shell-Scripting]# cat utils.sh

log_message() {

    local level=$1

    local message=$2

    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")


    case "$level" in

        "INFO")  echo -e "[$timestamp] \e[32mINFO\e[0m: $message" ;;

        "ERROR") echo -e "[$timestamp] \e[31mERROR\e[0m: $message" ;;

        *)       echo -e "[$timestamp] DEBUG: $message" ;;

    esac

}

[root@oel01db Shell-Scripting]#


Create a simple script to check the existance of a user and its primary group and let's source above script .


[root@oel01db Shell-Scripting]# cat deploy.sh

#!/bin/bash


# 1. Source the utility functions

# Make sure utils.sh is in the same directory!

source ./utils.sh


# 2. Capture the first argument

USERNAME=$1


# 3. Validation: Check if the user provided an argument

if [ -z "$USERNAME" ]; then

    log_message "ERROR" "No username provided. Usage: $0 <username>"

    exit 1

fi


log_message "INFO" "Checking existence of user: $USERNAME"


# 4. Logic: Search for the username in /etc/passwd

if id "$USERNAME" &>/dev/null; then

    log_message "INFO" "User '$USERNAME' exists on this system."


    # Optional: Show their primary group

    USER_GROUP=$(id -gn "$USERNAME")

    log_message "INFO" "Primary group for $USERNAME: $USER_GROUP"

else

    log_message "ERROR" "User '$USERNAME' does not exist."

    exit 1

fi

[root@oel01db Shell-Scripting]#

How  "if id "$USERNAME" &>/dev/null; then" works ? 

In Bash, if doesn't just check for "true" or "false." It specifically checks the Exit Status of the command that follows it.

  • If the exit status is 0 (Success), it runs the code after then.

  • If the exit status is anything else (Failure), it jumps to the else block.


















How to use -p with source

[root@oel01db Shell-Scripting]# ls -lrt
total 8
-rw-r--r-- 1 root root 340 Dec 23 10:01 utils.sh
-rw-r--r-- 1 root root 765 Dec 23 10:02 deploy.sh
drwxr-xr-x 2 root root   6 Dec 23 10:17 lib
[root@oel01db Shell-Scripting]# cp utils.sh lib/
[root@oel01db Shell-Scripting]#


[root@oel01db Shell-Scripting]# cat deploy_lib.sh
#!/bin/bash

# 1. Source the utility functions using libdirs

libdirs=./lib

. -p "$libdirs" utils.sh

# 2. Capture the first argument
USERNAME=$1

# 3. Validation: Check if the user provided an argument
if [ -z "$USERNAME" ]; then
    log_message "ERROR" "No username provided. Usage: $0 <username>"
    exit 1
fi

log_message "INFO" "Checking existence of user: $USERNAME"

# 4. Logic: Search for the username in /etc/passwd
if id "$USERNAME" &>/dev/null; then
    log_message "INFO" "User '$USERNAME' exists on this system."

    # Optional: Show their primary group
    USER_GROUP=$(id -gn "$USERNAME")
    log_message "INFO" "Primary group for $USERNAME: $USER_GROUP"
else
    log_message "ERROR" "User '$USERNAME' does not exist."
    exit 1
fi

[root@oel01db Shell-Scripting]#


Sometime you may want to put some code that you want to execute only when source fail for any reason in that case you can use 



[root@oel01db Shell-Scripting]# cat utils.sh

log_message() {

    local level=$1

    local message=$2

    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")


    case "$level" in

        "INFO")  echo -e "[$timestamp] \e[32mINFO\e[0m: $message" ;;

        "ERROR") echo -e "[$timestamp] \e[31mERROR\e[0m: $message" ;;

        *)       echo -e "[$timestamp] DEBUG: $message" ;;

    esac

}


if ! ( return 2> /dev/null); then


      log_message "hi" "hello there"


fi


[root@oel01db Shell-Scripting]# cat deploy.sh

#!/bin/bash


# 1. Source the utility functions

# Make sure utils.sh is in the same directory!

source ./utils.sh


# 2. Capture the first argument

USERNAME=$1


# 3. Validation: Check if the user provided an argument

if [ -z "$USERNAME" ]; then

    log_message "ERROR" "No username provided. Usage: $0 <username>"

    exit 1

fi


log_message "INFO" "Checking existence of user: $USERNAME"


# 4. Logic: Search for the username in /etc/passwd

if id "$USERNAME" &>/dev/null; then

    log_message "INFO" "User '$USERNAME' exists on this system."


    # Optional: Show their primary group

    USER_GROUP=$(id -gn "$USERNAME")

    log_message "INFO" "Primary group for $USERNAME: $USER_GROUP"

else

    log_message "ERROR" "User '$USERNAME' does not exist."

    exit 1

fi

[root@oel01db Shell-Scripting]#

[root@oel01db Shell-Scripting]# sh utils.sh

[2025-12-23 13:57:16] DEBUG: hello there

[root@oel01db Shell-Scripting]#

[root@oel01db Shell-Scripting]# sh deploy.sh mahesh

[2025-12-23 13:57:25] INFO: Checking existence of user: mahesh

[2025-12-23 13:57:25] INFO: User 'mahesh' exists on this system.

[2025-12-23 13:57:25] INFO: Primary group for mahesh: mahesh

[root@oel01db Shell-Scripting]#




Why "hello there" is not executed when we sourced the first script inside deploy.sh?

The command return is only valid inside a function or a sourced script.

  1. When you run sh utils.sh directly: utils.sh is executed as a standalone script and return is NOT allowed in a normal script. The ! (NOT) operator turns that failure into a "true" condition, so the code inside the if block executes. This is why you see "hello there".

  2. When you run source ./utils.sh (inside deploy.sh): The script is being loaded into the current shell environment. In this context, return is a valid command. Because return succeeds, the ! operator makes the condition "false," and the code inside the if block is skipped.


In the context of shell scripting, "returning" doesn't mean the script is sending back a specific piece of data (like a string or a number). Instead, it refers to the exit status of the command and how the shell handles the flow of execution.

[root@oel01db Shell-Scripting]# (return)
-bash: return: can only `return' from a function or sourced script
[root@oel01db Shell-Scripting]#


The "Failed" Return

When you run sh utils.sh, the shell executes the line ( return 2> /dev/null ).

  1. The shell says: "You're trying to return, but you aren't inside a function or a sourced script!"

  2. It generates an error exit status (usually 2 in most shells, but any non-zero number counts as a failure).

  3. The ! (logical NOT) takes that failure and turns it into True.

  4. The if block executes.




No comments:

Post a Comment

JFrog Artifactory - How to install

JFrog Artifactory OSS Installation Guide CentOS 9 + PostgreSQL 17 This guide provides a structured workflow to install JFrog Artifactory OSS...