Sample Header Ad - 728x90

Issue with `BASH_LINENO` in bash function which get debugging information

1 vote
1 answer
81 views
In Visual Code, on Windows 10, I'm trying to create a function for my .sh project (*which I run with Git Bash*), which will report errors to the console in case user, let's say, provides fewer or more parameters for a function. For this reason, I created the file error_report.sh with the function ErrorReport.
#!/usr/bin/env bash

function ErrorReport()
{
    local caller_func="${FUNCNAME}"
    local caller_file="$(basename "${BASH_SOURCE}")"
    local caller_line="${BASH_LINENO}"
    local caller_code="$(sed -n "${caller_line}p" "${BASH_SOURCE}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
    printf "\nCaller: ${caller_func}()"
    printf "\nFile  : ${caller_file}"
    printf "\nLine  : ${caller_line}"
    printf "\nCode  : ${caller_code}"
}
As main file of my project, I have temporarily created the tester_copy.sh where I have the following:
#!/usr/bin/env bash

declare -g script_dir="$(cd "$(dirname "${BASH_SOURCE}")" && pwd)"

source "${script_dir}/lib/ui/window_manager.sh"
source "${script_dir}/error_report.sh"

function TestFunction()
{
    if [[ "$#" -ne 3 ]]; then
        ErrorReport
        return 1
    fi

    local arg1="$1"
    local arg2="$2"
    local arg3="$3"

    echo "arguments: $arg1, $arg2, $arg3"
}

function Main()
{
    ConsoleWindowSetup "${MMS_WINDOW_TITLE}" 40 120

    clear

    TestFunction "11111" "22222"

    read -re -p ""
}

Main "$@"
The problem is that in my console, displays Caller and File correctly, but Line and Code incorrectly. Instead of displaying Line: 28 and Code: TestFunction "11111" "22222", it displays:
Caller: Main()
File  : tester_copy.sh
Line  : 6
Code  : source "${script_dir}/error_report.sh"
But if I change my main script to:
#!/usr/bin/env bash

declare -g script_dir="$(cd "$(dirname "${BASH_SOURCE}")" && pwd)"

source "${script_dir}/lib/ui/window_manager.sh"
source "${script_dir}/error_report.sh"

function TestFunction()
{
    if [[ "$#" -ne 3 ]]; then
        ErrorReport
        return 1
    fi

    local arg1="$1"
    local arg2="$2"
    local arg3="$3"

    echo "Λήφθηκαν τα arguments: $arg1, $arg2, $arg3"
}

ConsoleWindowSetup "${MMS_WINDOW_TITLE}" 40 120
clear

TestFunction "11111" "22222"

read -re -p ""
If I take the main code outside the function Main(), then it displays correctly in the console...
Caller: main()
File  : tester_copy.sh
Line  : 28
Code  : TestFunction "11111" "22222"
Which I don't want though because ErrorReport is intended for errors inside functions. Why is this happening and how can I make it work when the error is inside a function? ##### Debugging (17/05/2025) * If I copy the whole .sh project into my Ubuntu Server it works even if the error is inside a function. * It also works using WSL. * I am almost sure that the problem happens only if I run the .sh file from Windows, by just double clicking on it. In any other case, works fine. ##### Debugging (18/05/2025) The default application on this Windows computer to open .sh files is "C:\Program Files\Git\git-bash.exe". When I open my .sh file by double-clicking, the problem I mentioned occurs. However, if I try running it by dragging the file to "C:\Program Files\Git\bin\bash.exe", "C:\Program Files\Git\bin\sh.exe" or "C:\Program Files\Git\git-bash.exe", it works fine in all three! I tried creating a shortcut with the target "C:\Program Files\Git\git-bash.exe" --cd="C:\Users\***\Desktop\PROGRAMMING\SH\sigma_sh_lib" -c "./tester_copy.sh" and it also works fine! Then I created a function to get debug shell info...
DebugShellInfo() {
    echo "================= DEBUG INFO ================="
    printf "🔹 Shell Script Name     : %s\n" "$0"
    printf "🔹 Declared Interpreter  : %s\n" "${SHELL:-}"
    printf "🔹 Bash Version          : %s\n" "${BASH_VERSION:-}"

    # FUNCNAME stack
    printf "🔹 FUNCNAME Stack        :"
    if [[ ${#FUNCNAME[@]} -eq 0 ]]; then
        echo " "
    else
        echo " ${FUNCNAME}"
        for ((i = 1; i "
    else
        echo " ${BASH_SOURCE}"
        for ((i = 1; i "
    else
        echo " ${BASH_LINENO}"
        for ((i = 1; i < ${#BASH_LINENO[@]}; i++)); do
            printf "                           %s\n" "${BASH_LINENO[i]}"
        done
    fi

    echo "=============================================="
}
Now, when I called it, I noticed the following. When it is called while the file is running by double-clicking it outputs...
================= DEBUG INFO =================
🔹 Shell Script Name     : C:\Users\***\Desktop\PROGRAMMING\SH STUFF\sigma_sh_lib\tester_copy.sh
🔹 Declared Interpreter  : /usr/bin/bash
🔹 Bash Version          : 5.2.37(1)-release
🔹 FUNCNAME Stack        : DebugShellInfo
                           MSG
                           MSG
                           Main
                           main
🔹 BASH_SOURCE Stack     : /c/Users/***/Desktop/PROGRAMMING/SH STUFF/sigma_sh_lib/lib/utils/debug_shell_info.sh
                           /c/Users/***/Desktop/PROGRAMMING/SH STUFF/sigma_sh_lib/lib/ui/msg.sh
                           /c/Users/***/Desktop/PROGRAMMING/SH STUFF/sigma_sh_lib/lib/ui/msg.sh
                           C:\Users\***\Desktop\PROGRAMMING\SH STUFF\sigma_sh_lib\tester_copy.sh
                           C:\Users\***\Desktop\PROGRAMMING\SH STUFF\sigma_sh_lib\tester_copy.sh
🔹 BASH_LINENO Stack     : 130
                           1
                           14
                           70
                           0
==============================================
But when it is called with the other ways I mentioned above, it outputs...
================= DEBUG INFO =================
🔹 Shell Script Name     : ./tester_copy.sh
🔹 Declared Interpreter  : /usr/bin/bash
🔹 Bash Version          : 5.2.37(1)-release
🔹 FUNCNAME Stack        : DebugShellInfo
                           MSG
                           MSG
                           Main
                           main
🔹 BASH_SOURCE Stack     : /c/Users/***/Desktop/PROGRAMMING/SH STUFF/sigma_sh_lib/lib/utils/debug_shell_info.sh
                           /c/Users/***/Desktop/PROGRAMMING/SH STUFF/sigma_sh_lib/lib/ui/msg.sh
                           /c/Users/***/Desktop/PROGRAMMING/SH STUFF/sigma_sh_lib/lib/ui/msg.sh
                           ./tester_copy.sh
                           ./tester_copy.sh
🔹 BASH_LINENO Stack     : 194
                           95
                           60
                           70
                           0
==============================================
Notice the differences in the "Shell Script Name" paths and in "BASH_SOURCE Stack" and "BASH_LINENO Stack" paths!!! **Note**: I moved the code of ErrorReport function into a function called MSG.
Asked by Simos Sigma (111 rep)
May 17, 2025, 09:04 AM
Last activity: May 19, 2025, 07:43 AM