Reputation: 3138
How can I achieve the following with Bash:
x="search='something something' replace='something' subject=/path/path"
eval "$x"
echo $search
# prints something
# etc.
# (I am trying to do something here)
# So the following wouldn't print **something** anymore
echo $search
I basically want to unset the variables that were set using eval initially.
Upvotes: 1
Views: 180
Reputation: 70967
Preamble: Care using eval
as eval is evil...
Whatever...
unset ${x//=*([^ ])}
As pointed out by glenn jackman, this work only if there are no spaces in content of variables.
In this case, we could (very quickly too) prepare some intermediary variable (x without spaces
):
xwos=${x//\"*([^\"])\"} # This will drop `search="don't know"`
xwos=${xwos//\'*([^\'])\'} # This will drop `search='blah blah'`
unset ${xwos//=*([^ ])}
In fine, adding this to your script will do the job:
xwos=${x//\"*([^\"])\"}; xwos=${xwos//\'*([^\'])\'}; unset ${xwos//=*([^ ])}
Of course, you have to use extglob
bash's option, if not already set:
shopt -s extglob
Let's try:
x="search='something something' replace='something' subject=/path/path"
eval "$x"
echo $search
something something
declare -p search replace subject
declare -- search="something something"
declare -- replace="something"
declare -- subject="/path/path"
shopt -s extglob
xwos=${x//\"*([^\"])\"}
printf 'X w/o double quoted spaces 1st:\n "%s"\n' "$xwos"
X w/o double quoted spaces 1st:
"search='something something' replace='something' subject=/path/path"
xwos=${xwos//\'*([^\'])\'}
printf 'X w/o single quoted spaces 2nd:\n "%s"\n' "$xwos"
X w/o single quoted spaces 2nd:
"search= replace= subject=/path/path"
printf 'String containing variables w/o values:\n "%s"\n' "${xwos//=*([^ ])}"
String containing variables w/o values:
"search replace subject"
unset ${xwos//=*([^ ])}
declare -p search replace subject
bash: declare: search: not found
bash: declare: replace: not found
bash: declare: subject: not found
Nota: If you don't need x
anymore, you could redefine x
instead of populating a new variable:
shopt -s extglob;x=${x//\"*([^\"])\"};x=${x//\'*([^\'])\'};unset ${x//=*([^ ])}
x="search='something something' replace='something' subject=/path/path"
eval "$x"
echo $search
something something
shopt -s extglob;x=${x//\"*([^\"])\"};x=${x//\'*([^\'])\'};unset ${x//=*([^ ])}
echo $search
Upvotes: 3
Reputation: 785761
You can fork a subshell, do eval
in the subshell and once you're done, exit the subshell:
# do this in a subshell
(
x="search='something' replace='something' subject=/path"
eval "$x"
echo "search=$search"
)
# now out of subshell
echo "search=$search"
Upvotes: 3