假设我有以下内容:
eval link='/var/lib/${XYZ}/test' # string from another text file
XYZ仅用于示例,它可能类似于以下内容:
eval link='/var/lib/${MY_OWN_VAR}/test' # single quote here not double quotes
eval link='/var/lib/${WHAT_EVER}/test'
如果未设置XYZ
,是否有可能出错?还是有其他方法可以确定是否设置了XYZ
?
我看过this,但假设您知道变量名。就我而言,我无法控制要评估的字符串中的内容。
更新
为清楚起见,所有需要评估的字符串均来自文本文件。基本上,程序会读取文本文件, 输出评估的字符串。
我在这里尝试的所有工作是想出一种方法,在评估任何字符串时都能正常捕获“未绑定变量”错误。基本上是set -u
的功能,但是很优雅。
答案 0 :(得分:1)
您可以在实际执行评估之前在子外壳中测试评估:
assign_if_defined(){
echo 1>&2 "testing $1=$2"
outvar="$1"
input=${2@Q}
err=$(exec 2>&1; set -u; eval "${outvar}=${input@P}")
if [ -z "$err" ]; then
echo 1>&2 "eval test succeeded: doing for real"
eval "${outvar}=${input@P}"
else
echo 1>&2 "eval test failed: not doing for real"
echo 1>&2 "error: $err"
fi
}
A=set
assign_if_defined link1 "'"'"\/${A}/'
echo link1=$link1
unset B
assign_if_defined link2 '/$B/'
echo link2=$link2
似乎@Q
/ @P
转换首先出现在bash 4.4中。使用它们意味着简化了报价。如果使用较旧版本的bash,则可以尝试使用常规引号(eval "${outvar}=\"${input}\""
),但是如果input
包含特殊字符(如第一个示例),则代码将失败。
答案 1 :(得分:0)
我不确切知道您对字符串有多少控制(或知识),但是您不能只是测试它是否为空?
VAR=mydirectory
str=/var/lib/${VAR}/test # valid
str2=/var/lib/${NONEXISTANT}/test # invalid
if [[ "$str" = "/var/lib//test" ]] ;
then
echo 'is_empty';
else
echo 'is_set';
fi;
唯一的缺点是,如果您收到一个已设置但为空的变量,例如VAR=""