4
4
#
5
5
# @Usage
6
6
# source this script to your script file, then use func parseOpts.
7
- # parseOpts func useage sample:
7
+ # parseOpts func usage sample:
8
8
# $ 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:
10
10
# _OPT_VALUE_a = true
11
11
# _OPT_VALUE_a_long = true
12
12
# _OPT_VALUE_b = bv
19
19
# @author Jerry Lee (oldratlee at gmail dot com)
20
20
21
21
# ####################################################################
22
- # Util Funtions
22
+ # Util Functions
23
23
# ####################################################################
24
24
25
25
# NOTE: $'foo' is the escape sequence syntax of bash
26
26
readonly _opts_ec=$' \033 ' # escape char
27
27
readonly _opts_eend=$' \033 [0m' # escape end
28
28
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
32
37
fi
33
38
34
39
_opts_colorEcho () {
35
40
local color=$1
36
41
shift
37
42
# 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 " $* "
39
44
}
40
45
41
46
_opts_redEcho () {
@@ -44,7 +49,7 @@ _opts_redEcho() {
44
49
45
50
_opts_convertToVarName () {
46
51
[ $# -ne 1 ] && {
47
- _opts_redEcho " NOT 1 arguemnts when call _opts_convertToVarName: $@ "
52
+ _opts_redEcho " NOT 1 arguments when call _opts_convertToVarName: $* "
48
53
return 1
49
54
}
50
55
echo " $1 " | $_opts_SED_CMD ' s/-/_/g'
@@ -53,7 +58,7 @@ _opts_convertToVarName() {
53
58
# ####################################################################
54
59
# Parse Functions
55
60
#
56
- # Use Globle Variable:
61
+ # Use Globe Variable:
57
62
# * _OPT_INFO_LIST_INDEX : Option info, data structure.
58
63
# _OPT_INFO_LIST_INDEX ->* _a_a_long -> option value.
59
64
# * _OPT_VALUE_* : value of option. is Array type for + mode option
@@ -62,20 +67,21 @@ _opts_convertToVarName() {
62
67
63
68
_opts_findOptMode () {
64
69
[ $# -ne 1 ] && {
65
- _opts_redEcho " NOT 1 arguemnts when call _opts_findOptMode: $@ "
70
+ _opts_redEcho " NOT 1 arguments when call _opts_findOptMode: $* "
66
71
return 1
67
72
}
68
73
69
74
local opt=" $1 " # like a, a-long
70
75
local idxName
71
76
for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
72
- local idxNameArrayPlaceHolder=" $idxName [@]"
77
+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
73
78
local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
74
79
75
80
local mode=" ${idxNameArray[0]} "
76
81
77
82
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
79
85
[ " $opt " == " ${optName} " ] && {
80
86
echo " $mode "
81
87
return
@@ -88,7 +94,7 @@ _opts_findOptMode() {
88
94
89
95
_opts_setOptBool () {
90
96
[ $# -ne 2 ] && {
91
- _opts_redEcho " NOT 2 arguemnts when call _opts_setOptBool: $@ "
97
+ _opts_redEcho " NOT 2 arguments when call _opts_setOptBool: $* "
92
98
return 1
93
99
}
94
100
@@ -97,7 +103,7 @@ _opts_setOptBool() {
97
103
98
104
_opts_setOptValue () {
99
105
[ $# -ne 2 ] && {
100
- _opts_redEcho " NOT 2 arguemnts when call _opts_setOptValue: $@ "
106
+ _opts_redEcho " NOT 2 arguments when call _opts_setOptValue: $* "
101
107
return 1
102
108
}
103
109
@@ -106,17 +112,21 @@ _opts_setOptValue() {
106
112
107
113
local idxName
108
114
for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
109
- local idxNameArrayPlaceHolder=" $idxName [@]"
115
+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
110
116
local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
111
117
112
118
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
114
121
[ " $opt " == " $optName " ] && {
115
122
local optName2
116
123
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
118
127
local from=' "$value"'
119
- eval " $optValueVarName =$from " # set global var!
128
+ # set global var!
129
+ eval " $optValueVarName =$from "
120
130
done
121
131
return
122
132
}
@@ -133,16 +143,18 @@ _opts_setOptArray() {
133
143
134
144
local idxName
135
145
for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
136
- local idxNameArrayPlaceHolder=" $idxName [@]"
146
+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
137
147
local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
138
148
139
149
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
141
152
[ " $opt " == " $optName " ] && {
142
153
# set _OPT_VALUE
143
154
local optName2
144
155
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} " ) "
146
158
local from=' "$@"'
147
159
eval " $optValueVarName =($from )" # set global var!
148
160
done
@@ -158,14 +170,16 @@ _opts_setOptArray() {
158
170
_opts_cleanOptValueInfoList () {
159
171
local idxName
160
172
for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
161
- local idxNameArrayPlaceHolder=" $idxName [@]"
173
+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
162
174
local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
163
175
164
176
eval " unset $idxName "
165
177
166
178
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 " ) "
169
183
eval " unset $optValueVarName "
170
184
done
171
185
done
@@ -180,56 +194,61 @@ parseOpts() {
180
194
181
195
_OPT_INFO_LIST_INDEX=() # set global var!
182
196
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
+ )
187
203
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
190
206
[ -z " $optDesc " ] && continue
191
207
192
- local mode=" ${optDesc: (-1)} " # LIKE : or +
208
+ # LIKE : or +
209
+ local mode=" ${optDesc: (-1)} "
193
210
case " $mode " in
194
211
+ | : | -)
195
- optDesc=" ${optDesc: 0: (${# optDesc} - 1)} " # LIKE b,b-long
212
+ # LIKE b,b-long
213
+ optDesc=" ${optDesc: 0: (${# optDesc} - 1)} "
196
214
;;
197
215
* )
198
216
mode=" -"
199
217
;;
200
218
esac
201
219
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}' ) "
203
222
204
- [ $( echo " $optLines " | wc -l) -gt 2 ] && {
223
+ [ " $( echo " $optLines " | wc -l) " -gt 2 ] && {
205
224
_opts_redEcho " Illegal option description($optDesc ), more than 2 opt name!" 1>&2
206
225
_opts_cleanOptValueInfoList
207
226
return 220
208
227
}
209
228
210
229
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
213
232
[ -z " $opt " ] && continue
214
233
215
- [ ${# opt} -eq 1 ] && {
234
+ if [ ${# opt} -eq 1 ]; then
216
235
echo " $opt " | grep -E ' ^[a-zA-Z0-9]$' -q || {
217
236
_opts_redEcho " Illegal short option name($opt in $optDesc ) in option description!" 1>&2
218
237
_opts_cleanOptValueInfoList
219
238
return 221
220
239
}
221
- } || {
240
+ else
222
241
echo " $opt " | grep -E ' ^[-a-zA-Z0-9]+$' -q || {
223
242
_opts_redEcho " Illegal long option name($opt in $optDesc ) in option description!" 1>&2
224
243
_opts_cleanOptValueInfoList
225
244
return 222
226
245
}
227
- }
246
+ fi
228
247
optTuple=(" ${optTuple[@]} " " $opt " )
229
248
done < <( echo " $optLines " )
230
249
231
250
[ ${# 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
233
252
_opts_cleanOptValueInfoList
234
253
return 223
235
254
}
@@ -263,8 +282,10 @@ parseOpts() {
263
282
;;
264
283
-* ) # short & long option(-a, -a-long), use same read-in logic.
265
284
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 " )
268
289
case " $mode " in
269
290
-)
270
291
_opts_setOptBool " $optName " " true"
@@ -292,7 +313,7 @@ parseOpts() {
292
313
} || valueArray=(" ${valueArray[@]} " " $value " )
293
314
done
294
315
[ " $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
296
317
_opts_cleanOptValueInfoList
297
318
return 231
298
319
}
@@ -312,7 +333,8 @@ parseOpts() {
312
333
;;
313
334
esac
314
335
done
315
- _OPT_ARGS=(" ${args[@]} " ) # set global var!
336
+ # set global var!
337
+ _OPT_ARGS=(" ${args[@]} " )
316
338
}
317
339
318
340
# ####################################################################
@@ -324,7 +346,7 @@ _opts_showOptDescInfoList() {
324
346
echo " show option desc info list:"
325
347
local idxName
326
348
for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
327
- local idxNameArrayPlaceHolder=" $idxName [@]"
349
+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
328
350
echo " $idxName = (${! idxNameArrayPlaceHolder} )"
329
351
done
330
352
echo " ==============================================================================="
@@ -335,14 +357,16 @@ _opts_showOptValueInfoList() {
335
357
echo " show option value info list:"
336
358
local idxName
337
359
for idxName in " ${_OPT_INFO_LIST_INDEX[@]} " ; do
338
- local idxNameArrayPlaceHolder=" $idxName [@]"
360
+ local idxNameArrayPlaceHolder=" ${ idxName} [@]"
339
361
local -a idxNameArray=(" ${! idxNameArrayPlaceHolder} " )
340
362
341
363
local mode=${idxNameArray[0]}
342
364
343
365
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 " ) "
346
370
case " $mode " in
347
371
-)
348
372
echo " $optValueVarName =${! optValueVarName} "
@@ -351,12 +375,12 @@ _opts_showOptValueInfoList() {
351
375
echo " $optValueVarName =${! optValueVarName} "
352
376
;;
353
377
+)
354
- local optArrayValueArrayPlaceHolder=" $optValueVarName [@]"
378
+ local optArrayValueArrayPlaceHolder=" ${ optValueVarName} [@]"
355
379
echo " $optValueVarName =(${! optArrayValueArrayPlaceHolder} )"
356
380
;;
357
381
esac
358
382
done
359
383
done
360
- echo " _OPT_ARGS=(${_OPT_ARGS[@ ]} )"
384
+ echo " _OPT_ARGS=(${_OPT_ARGS[* ]} )"
361
385
echo " ==============================================================================="
362
386
}
0 commit comments