うーん、私はパーティーに遅れているようです :)
スクリプトの前に渡された環境変数を処理する方法は次のとおりです。
まず第一に、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
正しく機能します。
これで、入力の一部を反復処理できます。
vars を宣言してスクリプトを実行する方法の例を次に示します。
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
この反復子は、次の 2 つの単純なことを行っています。
SOME_VAR=
式に一致するチャンクの場合は var を宣言する
- それ以外の場合は、最終的なコマンドにチャンクを追加します
したがって、出力は次のようになります。
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
これはあなたのニーズに近いですか?