-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbash_lib.sh
More file actions
180 lines (160 loc) · 4.73 KB
/
bash_lib.sh
File metadata and controls
180 lines (160 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env bash
parse_args_help() {
cat <<-EOF
This bash function helps to parse cmd line arguments
It takes a list of understood option (short/long), for which their values can
be assigned to a specified variable.
Usage : parse_args "list of options understood" "original command line"
The list is space element separated. Each element must be an option, and can
be followed by an equal sign, "=", and a bash-like variable name.
If a variable is given, and the option associated is found, then the variable
is filled with the corresponding value.
Setting PARSE_VERBOSE to 'y' will cause the function to be verbose on what it
does
Extra functions :
- parse_args_get_opt_val <option> <list_of_options>
Outputs an option and the variable associated if presents
- parse_args_echo_vars var1 var2 ...
Outputs the variables given and their contents
- parse_args_test_func <cmd_line>
Simulates a call to a function that calls itself parse_args
- parse_args_call_test_func
Simulates the call to parse_args_test_func
Example :
my_func() {
parse_args "-s=varS --long=varL --alone" "\$@"
}
$ PARSE_VERBOSE=y my_func -s "something" --alone --long="like that" -e "oh yeah"
-s=varS --long=varL --alone
Short option '-s' => varS='something'
Long option '--alone'
Long option '--long' => varL='like that'
Value '-e' saved
Value 'oh yeah' saved
=== Checking Global vars
PA_AO : --alone
PA_R : "-e" "oh yeah"
$ parse_args_echo_vars varS varL
=== Checking vars...
varS = 'something'
varL = 'like that'
EOF
}
parse_args_logger() {
[ "${PARSE_VERBOSE}" != "y" ] || echo "$@"
}
# $1 : option needed
# $2 : command line
parse_args_get_opt_val() {
sed -nr "s/.*-${1:1}(=?([^[:blank:]]*)).*/$1 \2/p" <<<"$2"
}
# Arg 1 : option=var-name option
# PARSE_VERBOSE=y -> verbose
# PA_AO and PA_R : Output
# TODO Add possibility to give PA_R/PA_AO names
parse_args() {
local options="$(printf "%s\n" "$1")"; shift
local cmdl="$@"
local curO curV
# If set, do not update the current read value
# cur & val : the option and its value
# --cur=val || --cur val
local keep=0 cur val
# Current Short option
local cso
# Set to the number of args consumed
local toshift
# Set to 1 if $1 needs to be saved in PA_R
local save
unset PA_AO PA_R
declare -Ag PA_AO
declare -g PA_R
parse_args_logger $options
while [[ $# -ne 0 ]]; do
save=0
toshift=1
[ "$keep" = "0" ] && {
read cur val<<<$(echo "$1" | sed 's/=/ /')
[ -z "$val" ] && {
val="$2"
toshift=2
}
}
keep=0
case "$cur" in
--)
parse_args_logger "Option '--' found, saving all others into PA_R..."
shift
while [[ $# -ne 0 ]]; do
PA_R+=" '$1'"; shift
done
;;
--* )
read curO curV <<<$(parse_args_get_opt_val "$cur" "$options")
if [[ -z "$curO" ]]; then
cso="$1"
parse_args_logger "Long option '$cso' saved"
save=1
else
parse_args_logger -n "Long option '$cur' "
if [[ -z "$curV" ]]; then
PA_AO["$curO"]=1
parse_args_logger
shift
else
parse_args_logger "=> $curV='$val'"
eval declare -g \"$curV="$val"\"
shift $toshift
fi
fi
;;
-* )
cso="-${cur:1:1}"
[ ${#cur} -ne 2 ] && {
keep=1
cur="-${cur:2}"
}
read curO curV <<<$(parse_args_get_opt_val "$cso" "$options")
if [[ -z "$curO" ]]; then
parse_args_logger -en "Short option '$cso' saved"
save=1
else
parse_args_logger -n "Short option '$cur' "
if [[ -z "$curV" ]]; then
PA_AO["$curO"]=1
parse_args_logger
[ "$keep" = 1 ] || shift
else
parse_args_logger "=> $curV='$val'"
eval declare -g \"$curV="$val"\"
shift $toshift
fi
fi
;;
* )
cso="$1"
parse_args_logger "Value '$cso' saved"
save=1
shift
;;
esac
[ "$save" = "1" ] && PA_R+=" \"$cso\""
done
parse_args_logger -e "\n=== Checking Global vars"
parse_args_logger "PA_AO : ${!PA_AO[@]}"
parse_args_logger "PA_R : ${PA_R}"
}
parse_args_echo_vars() {
echo "=== Checking vars..."
for i in $@; do
eval echo \"$i = \'\${$i}\'\"
done
}
parse_args_test_func() {
echo " -- Calling for '$@'"
parse_args "-p=my_option --other=letssee --verbose=verbosity --alone -y" "$@"
parse_args_echo_vars my_option letssee verbosity
}
parse_args_call_test_func() {
parse_args_test_func -p door -e something --verbose "Yes we can" --other="it works also" --alone -y -e "This is what I say"
}