Reputation: 3922
Let assume I have something like below:
eval link='/var/lib/${XYZ}/test' # string from another text file
XYZ is just for the the example and it could be anything like below:
eval link='/var/lib/${MY_OWN_VAR}/test' # single quote here not double quotes
eval link='/var/lib/${WHAT_EVER}/test'
Is it possible to error out if XYZ
is not set? or is there any other way to figure out if XYZ
is set or not?
I have looked at this, but the assumption there is that you know the variable name. In my case I have no control over what would be in the string to be evaluated.
UPDATE
To be clear, all the strings that needs to be evaluated are from a text file. basically a program reads a text file and outputs the evaluated strings.
All I am trying here is to figure out a way to gracefully catch "unbound variable" error while evaluating any string. basically what set -u
does but gracefully.
Upvotes: 0
Views: 651
Reputation: 16797
You can test the eval in a subshell before performing it for real:
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
It seems that the @Q
/@P
transformations first appeared in bash 4.4. Using them means that quoting is much simplified. If using an older version of bash, you could try normal quoting (eval "${outvar}=\"${input}\""
) but the code will fail if input
contains special characters (as the first example).
Upvotes: 1
Reputation: 2255
Well I don't know exactly how much control (or knowledge) you do have on the strings, but can't you just test if it's empty?
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;
The only downfall is that the test will fail if you receive a var that is set but empty, e.g. VAR=""
Upvotes: 0