parse quoted string in bash... just for fun

This commit is contained in:
AJ ONeal 2019-06-02 02:35:02 -06:00
parent 0426760211
commit bca5333171
2 changed files with 79 additions and 0 deletions

71
git-proxy/parseargs.sh Normal file
View File

@ -0,0 +1,71 @@
set -u
set -e
# ParseArgs will parse a string that contains quoted strings the same as bash does
# (same as most other *nix shells do). This is secure in the sense that it doesn't do any
# executing or interpeting. However, it also doesn't do any escaping, so you shouldn't pass
# these strings to shells without escaping them.
parseargs() {
notquote="-"
str=$1
declare -a m=()
s=""
# Strip leading space, then trailing space, then add a terminating space.
str="${str## }"
str="${str%% }"
str+=" "
last_quote="${notquote}"
is_space=""
n=$(( ${#str} - 1 ))
i=-1
for ((i=0;i<=$n;i+=1)); do
c="${str:$i:1}"
# If we're ending a quote, break out and skip this character
if [ "$c" == "$last_quote" ]; then
last_quote=$notquote
continue
fi
# If we're in a quote, count this character
if [ "$last_quote" != "$notquote" ]; then
s+=$c
continue
fi
# If we encounter a quote, enter it and skip this character
if [ "$c" == "'" ] || [ "$c" == '"' ]; then
is_space=""
last_quote=$c
continue
fi
# If it's a space, store the string
re="[[:space:]]+" # must be used as a var, not a literal
if [[ $c =~ $re ]]; then
if [ "0" == "$i" ] || [ -n "$is_space" ]; then
echo continue $i $is_space
continue
fi
is_space="true"
m+=("$s")
s=""
continue
fi
is_space=""
s+="$c"
done
if [ "$last_quote" != "$notquote" ]; then
>&2 echo "error"
return 1
fi
for arg in "${m[@]}"; do
echo "$arg"
done
return 0
}

View File

@ -0,0 +1,8 @@
# usage
source ./parseargs.sh
export -f parseargs
IFS=$'\r\n' GLOBIGNORE='*' args=($(parseargs "foo 'bar baz' qux *"))
echo '$@': "${args[@]}"
for arg in "${args[@]}"; do
echo "$arg"
done