Say I have a bash script file config.sh. It’s meant to be source’d by other scripts and variables defined is used as customization of the upper-level scripts.
The problem is, if config.sh has a temporary variable and its name conflicts with upper-level scripts’ variable, it breaks the upper-level one.
config.sh:
TMP1=abc
CONFIG_INPUT_DIR="$TMP1"/in
CONFIG_OUTPUT_DIR="$TMP1"/out
upper-level script:
TMP1=def
source config.sh
echo $TMP1
The last echo prints abc, not def.
Solution 1
My current solution is to append a random string to the temporary variable name to make it almost impossible to conflict. e.g:
TMP1_vFc9Uiew=abc
CONFIG_INPUT_DIR="$TMP1_vFc9Uiew"/in
CONFIG_OUTPUT_DIR="$TMP1_vFc9Uiew"/out
unset TMP1_vFc9Uiew
which is painful and makes the code hard to read, in addition not to be perfect.
Solution 2 using local keyword
After some searching, I’ve come to know local keyword.
But when I simply declare TMP1 as local, bash complains that config.sh: line 1: local: can only be used in a function.
So my another solution is to enclose whole config script as a function:
function config_func_rZ0Yqkpm() {
local TMP1=abc
CONFIG_INPUT_DIR="$TMP1"/in
CONFIG_OUTPUT_DIR="$TMP1"/out
}
config_func_rZ0Yqkpm
unset config_func_rZ0Yqkpm
which is better than previous solution in maintainability and readability, but there’s some possibility to conflict as well as solution 1.
Question
I want to know more robust and smart solution without any possibility to conflict.
Thanks.
A trick I learned from the
keychainutility is using one program to build asource-able file containing just the variables that you want to export from your program. You could modify your script toechothe variables you want to set and then source the output from your program:I used
echo FOO=barto simulate the larger script; your program is probably more involved. The important part is that you must modify your program to output the variables and values you would like to set, rather than just setting them. This lets you decide which variables to expose and which ones to hold private at the cost of another shell process.