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)