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 interpreting. 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 args=() s="" # Strip leading space, then trailing space, then end with space. str="${str## }" str="${str%% }" str+=" " last_quote="${notquote}" is_space="" n=$(( ${#str} - 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" args+=("$s") s="" continue fi is_space="" s+="$c" done if [ "$last_quote" != "$notquote" ]; then >&2 echo "error: quote not terminated" return 1 fi for arg in "${args[@]}"; do echo "$arg" done return 0 }