Saturday, January 27, 2024

[SOLVED] Why is calling source /path/to/my/file different in function than in ~/.bash_profile?

Issue

I'd like to keep count of how many times I run a command, so I created a file to store the count. When I run $ my_function, the goal is to overwrite the file with a new value. So far, success. But subsequently calling $ my_function yields the same result and does not overwrite the file again.

If I close the command line and re-start it, things work fine. I'm trying to figure out why calling $ source "$count_file_path" at the end of my_function is not having the same effect as when I call it in ~/.bash_profile. Any ideas?

${HOME}/bash/.bash_count

#!/bin/bash

declare MY_LDAP_MY_FUNCTION_COUNT=0

In my ~/.bash_profile, I source the file. When I run the command, I want to increment it and write it to the file.

${HOME}/bash/.bash_my_functions

my_function () {
    local count_file_path="${HOME}/bash/.bash_count"

    local curr_count="$MY_LDAP_MY_FUNCTION_COUNT"
    echo "curr_count: $curr_count"

    local incremented=$((curr_count+1))

    # Overwrite existing .bash_count file with new value
    printf '#!/bin/bash\n\ndeclare MY_LDAP_MY_FUNCTION_COUNT=%s\n' "$incremented" > "$count_file_path"

    source "$count_file_path"

    cat "$count_file_path" # same result every time unless I quit and restart the command line
}

Solution

It's not source that has a different meaning called within a function -- it's declare.

If you want to make it always create a global variable, add the -g argument:

declare -g MY_LDAP_MY_FUNCTION_COUNT=0

...or just stop using it altogether in favor of a simple assignment:

MY_LDAP_MY_FUNCTION_COUNT=0

One needs to do likewise when generating code (and should always use printf %q to ensure that one is generating eval-safe output -- also, note the deliberate lack of shebang when writing a file intended to be sourced rather than executed):

printf 'MY_LDAP_MY_FUNCTION_COUNT=%q\n' "$incremented" > "$count_file_path.$$" \
  && mv -- "$count_file_path.$$" "$count_file_path"


Answered By - Charles Duffy
Answer Checked By - Marie Seifert (WPSolving Admin)