44#
55# @Usage
66# source this script to your script file, then use func parseOpts.
7- # parseOpts func useage sample:
7+ # parseOpts func usage sample:
88# $ parseOpts "a,a-long|b,b-long:|c,c-long+" -a -b bv -c c.sh -p pv -q qv arg1 \; aa bb cc
9- # then below globle var is set:
9+ # then below global var is set:
1010# _OPT_VALUE_a = true
1111# _OPT_VALUE_a_long = true
1212# _OPT_VALUE_b = bv
1919# @author Jerry Lee (oldratlee at gmail dot com)
2020
2121# ####################################################################
22- # Util Funtions
22+ # Util Functions
2323# ####################################################################
2424
2525# NOTE: $'foo' is the escape sequence syntax of bash
2626readonly _opts_ec=$' \033 ' # escape char
2727readonly _opts_eend=$' \033 [0m' # escape end
2828
29- _opts_SED_CMD=sed
30- if command -v gsed & > /dev/null; then
31- _opts_SED_CMD=gsed
29+ # shellcheck disable=SC2209
30+
31+ if [ -z " ${_opts_SED_CMD:- } " ]; then
32+ _opts_SED_CMD=sed
33+ if command -v gsed & > /dev/null; then
34+ _opts_SED_CMD=gsed
35+ fi
36+ readonly _opts_SED_CMD
3237fi
3338
3439_opts_colorEcho () {
3540 local color=$1
3641 shift
3742 # if stdout is console, turn on color output.
38- [ -t 1 ] && echo " $_opts_ec [1;${color} m$@ $ _opts_eend" || echo " $@ "
43+ [ -t 1 ] && echo " ${ _opts_ec} [1;${color} m$* ${ _opts_eend} " || echo " $* "
3944}
4045
4146_opts_redEcho () {
@@ -44,7 +49,7 @@ _opts_redEcho() {
4449
4550_opts_convertToVarName () {
4651 [ $# -ne 1 ] && {
47- _opts_redEcho " NOT 1 arguemnts when call _opts_convertToVarName: $@ "
52+ _opts_redEcho " NOT 1 arguments when call _opts_convertToVarName: $* "
4853 return 1
4954 }
5055 echo " $1 " | $_opts_SED_CMD ' s/-/_/g'
@@ -53,7 +58,7 @@ _opts_convertToVarName() {
5358# ####################################################################
5459# Parse Functions
5560#
56- # Use Globle Variable:
61+ # Use Globe Variable:
5762# * _OPT_INFO_LIST_INDEX : Option info, data structure.
5863# _OPT_INFO_LIST_INDEX ->* _a_a_long -> option value.
5964# * _OPT_VALUE_* : value of option. is Array type for + mode option
@@ -62,20 +67,21 @@ _opts_convertToVarName() {
6267
6368_opts_findOptMode () {
6469 [ $# -ne 1 ] && {
65- _opts_redEcho " NOT 1 arguemnts when call _opts_findOptMode: $@ "
70+ _opts_redEcho " NOT 1 arguments when call _opts_findOptMode: $* "
6671 return 1
6772 }
6873
6974 local opt=" $1 " # like a, a-long
7075 local idxName
7176 for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
72- local idxNameArrayPlaceHolder=" $idxName [@]"
77+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
7378 local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
7479
7580 local mode=" ${idxNameArray[0]} "
7681
7782 local optName
78- for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do # index from 1, skip mode
83+ # index from 1, skip mode
84+ for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do
7985 [ " $opt " == " ${optName} " ] && {
8086 echo " $mode "
8187 return
@@ -88,7 +94,7 @@ _opts_findOptMode() {
8894
8995_opts_setOptBool () {
9096 [ $# -ne 2 ] && {
91- _opts_redEcho " NOT 2 arguemnts when call _opts_setOptBool: $@ "
97+ _opts_redEcho " NOT 2 arguments when call _opts_setOptBool: $* "
9298 return 1
9399 }
94100
@@ -97,7 +103,7 @@ _opts_setOptBool() {
97103
98104_opts_setOptValue () {
99105 [ $# -ne 2 ] && {
100- _opts_redEcho " NOT 2 arguemnts when call _opts_setOptValue: $@ "
106+ _opts_redEcho " NOT 2 arguments when call _opts_setOptValue: $* "
101107 return 1
102108 }
103109
@@ -106,17 +112,21 @@ _opts_setOptValue() {
106112
107113 local idxName
108114 for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
109- local idxNameArrayPlaceHolder=" $idxName [@]"
115+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
110116 local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
111117
112118 local optName
113- for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do # index from 1, skip mode
119+ # index from 1, skip mode
120+ for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do
114121 [ " $opt " == " $optName " ] && {
115122 local optName2
116123 for optName2 in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do
117- local optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " ${optName2} " ) "
124+ local optValueVarName
125+ optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " ${optName2} " ) "
126+ # shellcheck disable=SC2016
118127 local from=' "$value"'
119- eval " $optValueVarName =$from " # set global var!
128+ # set global var!
129+ eval " $optValueVarName =$from "
120130 done
121131 return
122132 }
@@ -133,16 +143,18 @@ _opts_setOptArray() {
133143
134144 local idxName
135145 for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
136- local idxNameArrayPlaceHolder=" $idxName [@]"
146+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
137147 local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
138148
139149 local optName
140- for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do # index from 1, skip mode
150+ # index from 1, skip mode
151+ for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do
141152 [ " $opt " == " $optName " ] && {
142153 # set _OPT_VALUE
143154 local optName2
144155 for optName2 in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do
145- local optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " ${optName2} " ) "
156+ local optValueVarName
157+ optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " ${optName2} " ) "
146158 local from=' "$@"'
147159 eval " $optValueVarName =($from )" # set global var!
148160 done
@@ -158,14 +170,16 @@ _opts_setOptArray() {
158170_opts_cleanOptValueInfoList () {
159171 local idxName
160172 for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
161- local idxNameArrayPlaceHolder=" $idxName [@]"
173+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
162174 local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
163175
164176 eval " unset $idxName "
165177
166178 local optName
167- for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do # index from 1, skip mode
168- local optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " $optName " ) "
179+ # index from 1, skip mode
180+ for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do
181+ local optValueVarName
182+ optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " $optName " ) "
169183 eval " unset $optValueVarName "
170184 done
171185 done
@@ -180,56 +194,61 @@ parseOpts() {
180194
181195 _OPT_INFO_LIST_INDEX=() # set global var!
182196
183- local optDescLines=$( echo " $optsDescription " |
184- # cut head and tail space
185- $_opts_SED_CMD -r ' s/^\s+//;s/\s+$//' |
186- awk -F ' [\t ]*\\\\|[\t ]*' ' {for(i=1; i<=NF; i++) print $i}' )
197+ local optDescLines
198+ optDescLines=$(
199+ echo " $optsDescription " |
200+ $_opts_SED_CMD -r ' s/^\s+//;s/\s+$//' | # cut head and tail space
201+ awk -F ' [\t ]*\\|[\t ]*' ' {for(i=1; i<=NF; i++) print $i}'
202+ )
187203
188- local optDesc
189- while read optDesc; do # optDesc LIKE b,b-long:
204+ local optDesc # optDesc LIKE b,b-long:
205+ while read -r optDesc; do
190206 [ -z " $optDesc " ] && continue
191207
192- local mode=" ${optDesc: (-1)} " # LIKE : or +
208+ # LIKE : or +
209+ local mode=" ${optDesc: (-1)} "
193210 case " $mode " in
194211 + | : | -)
195- optDesc=" ${optDesc: 0: (${# optDesc} - 1)} " # LIKE b,b-long
212+ # LIKE b,b-long
213+ optDesc=" ${optDesc: 0: (${# optDesc} - 1)} "
196214 ;;
197215 * )
198216 mode=" -"
199217 ;;
200218 esac
201219
202- local optLines=$( echo " $optDesc " | awk -F ' [\t ]*,[\t ]*' ' {for(i=1; i<=NF; i++) print $i}' ) # LIKE "a\na-long"
220+ local optLines # LIKE "a\na-long"
221+ optLines=" $( echo " $optDesc " | awk -F ' [\t ]*,[\t ]*' ' {for(i=1; i<=NF; i++) print $i}' ) "
203222
204- [ $( echo " $optLines " | wc -l) -gt 2 ] && {
223+ [ " $( echo " $optLines " | wc -l) " -gt 2 ] && {
205224 _opts_redEcho " Illegal option description($optDesc ), more than 2 opt name!" 1>&2
206225 _opts_cleanOptValueInfoList
207226 return 220
208227 }
209228
210229 local -a optTuple=()
211- local opt
212- while read opt; do # opt LIKE a , a-long
230+ local opt # opt LIKE a , a-long
231+ while read -r opt; do
213232 [ -z " $opt " ] && continue
214233
215- [ ${# opt} -eq 1 ] && {
234+ if [ ${# opt} -eq 1 ]; then
216235 echo " $opt " | grep -E ' ^[a-zA-Z0-9]$' -q || {
217236 _opts_redEcho " Illegal short option name($opt in $optDesc ) in option description!" 1>&2
218237 _opts_cleanOptValueInfoList
219238 return 221
220239 }
221- } || {
240+ else
222241 echo " $opt " | grep -E ' ^[-a-zA-Z0-9]+$' -q || {
223242 _opts_redEcho " Illegal long option name($opt in $optDesc ) in option description!" 1>&2
224243 _opts_cleanOptValueInfoList
225244 return 222
226245 }
227- }
246+ fi
228247 optTuple=(" ${optTuple[@]} " " $opt " )
229248 done < <( echo " $optLines " )
230249
231250 [ ${# optTuple[@]} -gt 2 ] && {
232- _opts_redEcho " more than 2 opt(${optTuple[@ ]} ) in option description($optDesc )!" 1>&2
251+ _opts_redEcho " more than 2 opt(${optTuple[* ]} ) in option description($optDesc )!" 1>&2
233252 _opts_cleanOptValueInfoList
234253 return 223
235254 }
@@ -263,8 +282,10 @@ parseOpts() {
263282 ;;
264283 -* ) # short & long option(-a, -a-long), use same read-in logic.
265284 local opt=" $1 "
266- local optName=$( echo " $1 " | $_opts_SED_CMD -r ' s/^--?//' )
267- local mode=$( _opts_findOptMode " $optName " )
285+ local optName
286+ optName=$( echo " $1 " | $_opts_SED_CMD -r ' s/^--?//' )
287+ local mode
288+ mode=$( _opts_findOptMode " $optName " )
268289 case " $mode " in
269290 -)
270291 _opts_setOptBool " $optName " " true"
@@ -292,7 +313,7 @@ parseOpts() {
292313 } || valueArray=(" ${valueArray[@]} " " $value " )
293314 done
294315 [ " $foundComma " ] || {
295- _opts_redEcho " value of option $opt no end comma, value = ${valueArray[@ ]} " 1>&2
316+ _opts_redEcho " value of option $opt no end comma, value = ${valueArray[* ]} " 1>&2
296317 _opts_cleanOptValueInfoList
297318 return 231
298319 }
@@ -312,7 +333,8 @@ parseOpts() {
312333 ;;
313334 esac
314335 done
315- _OPT_ARGS=(" ${args[@]} " ) # set global var!
336+ # set global var!
337+ _OPT_ARGS=(" ${args[@]} " )
316338}
317339
318340# ####################################################################
@@ -324,7 +346,7 @@ _opts_showOptDescInfoList() {
324346 echo " show option desc info list:"
325347 local idxName
326348 for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
327- local idxNameArrayPlaceHolder=" $idxName [@]"
349+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
328350 echo " $idxName = (${! idxNameArrayPlaceHolder} )"
329351 done
330352 echo " ==============================================================================="
@@ -335,14 +357,16 @@ _opts_showOptValueInfoList() {
335357 echo " show option value info list:"
336358 local idxName
337359 for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
338- local idxNameArrayPlaceHolder=" $idxName [@]"
360+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
339361 local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
340362
341363 local mode=${idxNameArray[0]}
342364
343365 local optName
344- for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do # index from 1, skip mode
345- local optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " $optName " ) "
366+ # index from 1, skip mode
367+ for optName in " ${idxNameArray[@]: 1: ${# idxNameArray[@]} } " ; do
368+ local optValueVarName
369+ optValueVarName=" _OPT_VALUE_$( _opts_convertToVarName " $optName " ) "
346370 case " $mode " in
347371 -)
348372 echo " $optValueVarName =${! optValueVarName} "
@@ -351,12 +375,12 @@ _opts_showOptValueInfoList() {
351375 echo " $optValueVarName =${! optValueVarName} "
352376 ;;
353377 +)
354- local optArrayValueArrayPlaceHolder=" $optValueVarName [@]"
378+ local optArrayValueArrayPlaceHolder=" ${ optValueVarName} [@]"
355379 echo " $optValueVarName =(${! optArrayValueArrayPlaceHolder} )"
356380 ;;
357381 esac
358382 done
359383 done
360- echo " _OPT_ARGS=(${_OPT_ARGS[@ ]} )"
384+ echo " _OPT_ARGS=(${_OPT_ARGS[* ]} )"
361385 echo " ==============================================================================="
362386}
0 commit comments