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 }