Huh, seems i'm late to the party :)
Here is how i'm dealing with environment vars passed before script.
First off all, escape_args
function will escape spaces "inside" passed vars,
so if user pass VAR="foo bar"
, it will become VAR=foo\0040bar
.
function escape_args {
local str=''
local opt=''
for c in $1; do
if [[ "$c" =~ ^[[:alnum:]]+=[\"|\'] ]]; then
if [[ "${c: -1}" =~ [\"|\'] ]]; then
str="$str $( echo $c | xargs )"
else
# first opt chunk
# entering collector
opt="$c"
fi
else
if [ -z "$opt" ]; then
# not inside collector
str="$str $c"
else
# inside collector
if [[ "${c: -1}" =~ [\"|\'] ]]; then
# last opt chunk
# adding collected chunks and this last one to str
str="$str $( echo "$opt\0040$c" | xargs )"
# leaving collector
opt=''
else
# middle opt chunk
opt="$opt\0040$c"
fi
fi
fi
done
echo "$str"
}
Lets test it against a modified version of your input:
s="VAR1=\"some text here\" VAR2='some another text' VAR3=\"noSpaces\" VAR4='noSpacesToo' VAR5=noSpacesNoQuotes some script --with --some=args"
echo $(escape_args "$s")
VAR1=some\0040text\0040here VAR2=some\0040another\0040text VAR3=noSpaces VAR4=noSpacesToo VAR5=noSpacesNoQuotes some script --with --some=args
see, all vars are space-escaped and quotes removed, so declare
will work correctly.
Now you can iterate through the parts of your input.
Here is an example how you can declare vars and run the script:
cmd=''
for c in $(escape_args "$s"); do
[[ "$c" =~ ^[[:alnum:]]+= ]] && declare "$(echo -e $c)" && continue
cmd="$cmd $c"
done
echo VAR1 is set to $VAR1
echo VAR2 is set to $VAR2
echo VAR3 is set to $VAR3
echo VAR4 is set to $VAR4
echo VAR5 is set to $VAR5
echo $cmd
This iterator is doing two simple things:
- declaring a var if the chunk matching
SOME_VAR=
expression
- adding the chunk to the final cmd otherwise
so the output will be:
VAR1 is set to some text here
VAR2 is set to some another text
VAR3 is set to noSpaces
VAR4 is set to noSpacesToo
VAR5 is set to noSpacesNoQuotes
some script --with --some=args
Is this close to your needs?