73 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| 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
 | |
| }
 |