说我有一个bash脚本文件config.sh.它意味着由其他脚本提供源代码,定义的变量用作上层脚本的自定义.
问题是,如果config.sh有一个临时变量并且它的名称与高级脚本的变量冲突,它会破坏上层脚本的变量.
config.sh:
TMP1=abc
CONFIG_INPUT_DIR="$TMP1"/in
CONFIG_OUTPUT_DIR="$TMP1"/out
Run Code Online (Sandbox Code Playgroud)
上层脚本:
TMP1=def
source config.sh
echo $TMP1
Run Code Online (Sandbox Code Playgroud)
最后的echo印刷品abc,而不是def.
我目前的解决方案是将一个随机字符串附加到临时变量名称,使其几乎不可能发生冲突.例如:
TMP1_vFc9Uiew=abc
CONFIG_INPUT_DIR="$TMP1_vFc9Uiew"/in
CONFIG_OUTPUT_DIR="$TMP1_vFc9Uiew"/out
unset TMP1_vFc9Uiew
Run Code Online (Sandbox Code Playgroud)
这是痛苦的,使代码难以阅读,此外不是完美的.
local关键字经过一番搜索,我才知道local关键字.但是,当我简单地声明TMP1的local,bash的抱怨config.sh: line 1: local: can only be used in 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
Run Code Online (Sandbox Code Playgroud)
这在可维护性和可读性方面比以前的解决方案更好,但是有一些冲突的可能性以及解决方案1.
我想知道更强大和智能的解决方案,没有任何冲突的可能性.
谢谢.
我从该keychain实用程序中学到的一个技巧是使用一个程序来构建一个source只包含要从程序中导出的变量的文件.您可以将脚本修改为echo要设置的变量,然后从程序中获取输出:
$ echo $FOO
$ source <(echo FOO=bar)
$ echo $FOO
bar
$
Run Code Online (Sandbox Code Playgroud)
我曾经echo FOO=bar模拟过更大的剧本; 你的程序可能更复杂.重要的是,您必须修改程序以输出您想要设置的变量和值,而不是仅设置它们.这使您可以决定公开哪些变量以及以另一个shell进程为代价保留私有变量.
您可以避免变量并使用config.sh中的函数来保存您的值:
get_dirname() { echo "abc"; }
CONFIG_INPUT_DIR="$(get_dirname)/in"
CONFIG_OUTPUT_DIR="$(get_dirname)/out"
unset -f get_dirname
Run Code Online (Sandbox Code Playgroud)
如果您仍然担心函数的名称冲突,这对您没有帮助.
"ssh-agent"方法:
config.sh
#!/bin/bash
TMP=abc
printf "CONFIG_INPUT_DIR=%s/in" "$TMP"
printf "CONFIG_OUTPUT_DIR=%s/out" "$TMP"
Run Code Online (Sandbox Code Playgroud)
主程序:
TMP1=def
eval $(config.sh)
echo $TMP1
Run Code Online (Sandbox Code Playgroud)