难以在 bash 中使用 readlink 将变量和字符串混合到 return 绝对路径
Difficulty using readlink in bash with mix of variables and string to return absolute paths
我有一个配置脚本,用户可以在其中将路径指定为 header 部分中的变量。我希望他们能够使用绝对路径、相对路径和变量(因为这实际上是从另一个 shell 脚本调用的,他们从那里获取变量的值)。在脚本末尾,所有路径都写入文本文件。
我面临的挑战是某些路径中使用的变量可能会在脚本中间发生变化。我在 re-evaluating 获得正确输出的路径上遇到困难。
### 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
当我按照上面的方法做的时候遇到了'some condition','echo'的return是$VAR1/STRING1/Input
的绝对路径,而我想要的是abs路径$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' return 是评估变量和 un-evaluated 字符串的混合:$VAR2/STRING2/$DIR_PATH/Input
(对我来说)看起来像 /home/ubuntu/STRING2/$DIR_PATH/Input
。只是 $DIR_PATH/
不应该出现。
这个感觉应该比较直白吧。我希望我走在正确的道路上,这是我对 "" 和 '' 的错误使用。但是我尝试了很多变体都没有成功。
当您初始设置 InputDir_DEFAULT
时,它采用当前设置的值 ${DIR_PATH}
;即使您稍后更新 ${DIR_PATH}
,InputDir_DEFAULT
仍将保持之前的设置。要在当前脚本中解决此问题,您可以在 if
语句中再次设置 InputDir_DEFAULT
:
InputDir_DEFAULT=${DIR_PATH}/Input
此外,在您的第二次尝试中,单引号值设置转换为文字字符串值并且不会扩展为变量值:
InputDir_DEFAULT='$DIR_PATH/Input'
这是我最终得出的解决方案。它混合了@ThatsWhatSheCoded 和其他一些东西的建议,以确保用户不必在 header.
以外的任何地方重新定义变量。
我希望有更优雅的方法来执行此操作,但这确实有效。
### 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)
我有一个配置脚本,用户可以在其中将路径指定为 header 部分中的变量。我希望他们能够使用绝对路径、相对路径和变量(因为这实际上是从另一个 shell 脚本调用的,他们从那里获取变量的值)。在脚本末尾,所有路径都写入文本文件。
我面临的挑战是某些路径中使用的变量可能会在脚本中间发生变化。我在 re-evaluating 获得正确输出的路径上遇到困难。
### 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
当我按照上面的方法做的时候遇到了'some condition','echo'的return是$VAR1/STRING1/Input
的绝对路径,而我想要的是abs路径$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' return 是评估变量和 un-evaluated 字符串的混合:$VAR2/STRING2/$DIR_PATH/Input
(对我来说)看起来像 /home/ubuntu/STRING2/$DIR_PATH/Input
。只是 $DIR_PATH/
不应该出现。
这个感觉应该比较直白吧。我希望我走在正确的道路上,这是我对 "" 和 '' 的错误使用。但是我尝试了很多变体都没有成功。
当您初始设置 InputDir_DEFAULT
时,它采用当前设置的值 ${DIR_PATH}
;即使您稍后更新 ${DIR_PATH}
,InputDir_DEFAULT
仍将保持之前的设置。要在当前脚本中解决此问题,您可以在 if
语句中再次设置 InputDir_DEFAULT
:
InputDir_DEFAULT=${DIR_PATH}/Input
此外,在您的第二次尝试中,单引号值设置转换为文字字符串值并且不会扩展为变量值:
InputDir_DEFAULT='$DIR_PATH/Input'
这是我最终得出的解决方案。它混合了@ThatsWhatSheCoded 和其他一些东西的建议,以确保用户不必在 header.
以外的任何地方重新定义变量。我希望有更优雅的方法来执行此操作,但这确实有效。
### 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)