呵呵,看来我参加聚会迟到了:)
这是我如何处理在脚本之前传递的环境变量。
首先,escape_args
函数将转义“内部”传递的变量,
所以如果用户通过VAR="foo bar"
,它会变成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"
}
让我们针对您输入的修改版本对其进行测试:
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
看,所有的变量都是空格转义和引号被删除,所以declare
会正常工作。
现在您可以遍历输入的各个部分。
这是一个如何声明变量并运行脚本的示例:
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
这个迭代器做了两件简单的事情:
SOME_VAR=
如果块匹配表达式,则声明一个 var
- 否则将块添加到最终 cmd
所以输出将是:
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
这是否接近您的需求?