0

我有一个配置脚本,用户可以在其中将路径指定为标题部分中的变量。我希望他们能够使用绝对路径、相对路径和变量(因为这实际上是从另一个 shell 脚本调用的,他们从中获取变量的值)。在脚本结束时,所有路径都写入一个文本文件。

我面临的挑战是某些路径中使用的变量可能会在脚本中间发生变化。我在重新评估获得正确输出的路径时遇到了困难。

### HEADER SECTION ###
DIR_PATH="$VAR1/STRING1"
InputDir_DEFAULT="$DIR_PATH/Input"
### END HEADER ###

...some code

if [[ some condition ]]; then DIR_PATH="$VAR2/STRING2"; fi

...more code

# $InputDir_DEFAULT needs re-evaluating here
InputDir=$(readlink -m $InputDir_DEFAULT)
echo $InputDir >> $FILE

当我按照上面的操作并且满足“某些条件”时,“回声”的返回是 的绝对路径$VAR1/STRING1/Input,而我想要的是绝对路径$VAR2/STRING2/Input

下面是另一种选择,我尝试InputDir_DEFAULT通过将自身存储为字符串来停止评估直到结束。

### HEADER SECTION ###
DIR_PATH="$VAR1/STRING1"
InputDir_DEFAULT='$DIR_PATH/Input' #NOTE: "" marks have changed to ''
### END HEADER ###

if [[ some condition ]]; then DIR_PATH="$VAR2/STRING2"; fi

STRING_TMP=$InputDir_DEFAULT
InputDir=$(readlink -m $STRING_TMP)
echo $InputDir >> $FILE

这次 'echo' 返回已评估变量和未评估字符串的混合:($VAR2/STRING2/$DIR_PATH/Input对我而言)看起来像/home/ubuntu/STRING2/$DIR_PATH/Input. 它只是$DIR_PATH/不应该存在的。

这感觉应该相对简单。我希望我走在正确的道路上,这是我使用“”和“”的错误。但是我尝试了很多变化都没有成功。

4

2 回答 2

0

当您最初设置InputDir_DEFAULT时,它采用当前设置的值${DIR_PATH};即使您${DIR_PATH}稍后更新,InputDir_DEFAULT也将保持之前设置的状态。要在当前脚本中解决此问题,您可以在语句中InputDir_DEFAULT再次设置:if

InputDir_DEFAULT=${DIR_PATH}/Input

此外,在您的第二次尝试中,单引号值设置转换为文字字符串值,并且不会扩展为变量的值:

InputDir_DEFAULT='$DIR_PATH/Input'

我建议参考GNU Bash 手册中的“引用”部分

于 2020-05-15T22:24:10.720 回答
0

这是我最终得出的解决方案。它混合了@ThatsWhatSheCoded 和其他一些东西的建议,以确保用户不必在标题以外的任何地方重新定义变量。

我希望有一种更优雅的方式来做到这一点,但这确实有效。

### HEADER SECTION ###
DIR_PATH_DEFAULT="$VAR1/STRING1"
InputDir_DEFAULT="$DIR_PATH_DEFAULT/Input"
### END HEADER ###

...some code

if [[ some condition ]]; then DIR_PATH="$VAR2/STRING2"; fi

### Checks whether $DIR_PATH_DEFAULT is used in any variables.
### If so and $DIR_PATH is different, will replace string.
### This will be done for all variables in a list.
if [[ ! "$DIR_PATH_DEFAULT" =~ "$DIR_PATH" ]]; then
    for i in ${!var[@]}; do
        var_def_val=${var[i]}_DEFAULT
        STRING_TMP=${!var_def_val}
        var_def=${var[$i]}_DEFAULT
        if [[ $STRING_TMP == *"$DIR_PATH_DEFAULT"* ]] && [[ ! $var_def == "DIR_PATH_DEFAULT" ]]; then
            STRING_TMP="${STRING_TMP/$DIR_PATH_DEFAULT/$DIR_PATH}"
            eval "${var_def}=$STRING_TMP"
        fi
    done
fi

...more code

InputDir=$(readlink -m $InputDir_DEFAULT)
于 2020-05-28T00:01:53.597 回答