最后活跃于 1740031897

Taken from b167d3ec4e4f94d246ebdc4bcfdfb6ac

anthony's Avatar anthony 修订了这个 Gist 1740031896. 转到此修订

1 file changed, 158 insertions

args.sh(文件已创建)

@@ -0,0 +1,158 @@
1 + #!/usr/bin/env bash
2 +
3 + # Argument parser for bash scripts
4 + #
5 + # Author: Anthony Axenov (Антон Аксенов)
6 + # Version: 1.6
7 + # License: MIT
8 + # Description: https://git.axenov.dev/anthony/shell/src/branch/master/helpers/arg-parser
9 +
10 + #purpose Little helper to check if string matches PCRE
11 + #argument $1 - some string
12 + #argument $2 - regex
13 + #exitcode 0 - string valid
14 + #exitcode 1 - string is not valid
15 + grep_match() {
16 + printf "%s" "$1" | grep -qE "$2" >/dev/null
17 + }
18 +
19 + #purpose Find short argument or its value
20 + #argument $1 - (string) argument (without leading dashes; only first letter will be processed)
21 + #argument $2 - (number) is it flag? 1 if is, otherwise 0 or nothing
22 + #argument $3 - (string) variable to return value into
23 + # (if not specified then it will be echo'ed in stdout)
24 + #returns (string) 1 (if $2 == 1), value (if correct and if $2 != 1) or nothing
25 + #usage To get value into var: arg v 0 myvar or myvalue=$(arg 'v')
26 + #usage To find flag into var: arg f 1 myvar or flag=$(arg 'f')
27 + #usage To echo value: arg v
28 + #usage To echo 1 if flag exists: arg f
29 + arg() {
30 + [ "$1" ] || { echo "Argument name is not specified!" >&2 && exit 1; }
31 + local arg_name="${1:0:1}" # first character of argument name to find
32 + local is_flag="$2" || 0 # 1 if we need just find a flag, 0 to get a value
33 + local var_name="$3" || 0 # variable name to return value into or 0 to echo it in stdout
34 + local value= # initialize empty value to check if we found one later
35 + local arg_found=0 # marker of found argument
36 +
37 + for idx in "${!__RAW_ARGS__[@]}"; do # going through all args
38 + local arg_search=${__RAW_ARGS__[idx]} # get current argument
39 +
40 + # skip $arg_search if it starts with '--' or letter
41 + grep_match "$arg_search" "^(\w|--)" && continue
42 +
43 + # clear $arg_search from special and duplicate characters, e.g. 'fas-)dfs' will become 'fasd'
44 + local arg_chars="$(printf "%s" "$arg_search" \
45 + | tr -s "[$arg_search]" 2>/dev/null \
46 + | tr -d "[:punct:][:blank:]" 2>/dev/null)"
47 +
48 + # if $arg_name is not one of $arg_chars the skip it
49 + grep_match "-$arg_name" "^-[$arg_chars]$" || continue
50 + arg_found=1
51 +
52 + # then return '1'|'0' back into $value if we need flag or next arg value otherwise
53 + [ "$is_flag" = 1 ] && value=1 || value="${__RAW_ARGS__[idx+1]}"
54 + break
55 + done
56 +
57 + [ "$is_flag" = 1 ] && [ -z "$value" ] && value=0;
58 +
59 + # if value we found is empty or looks like another argument then exit with error message
60 + if [ "$arg_found" = 1 ] && ! grep_match "$value" "^[[:graph:]]+$" || grep_match "$value" "^--?\w+$"; then
61 + echo "ERROR: Argument '-$arg_name' must have correct value!" >&2 && exit 1
62 + fi
63 +
64 + # return '$value' back into $var_name (if exists) or echo in stdout
65 + [ "$var_name" ] && eval "$var_name='$value'" || echo "$value"
66 + }
67 +
68 + #purpose Find long argument or its value
69 + #argument $1 - argument (without leading dashes)
70 + #argument $2 - (number) is it flag? 1 if is, otherwise 0 or nothing
71 + #argument $3 - (string) variable to return value into
72 + # (if not specified then it will be echo'ed in stdout)
73 + #returns (string) 1 (if $2 == 1), value (if correct and if $2 != 1) or nothing
74 + #usage To get value into var: arg v 0 myvar or myvalue=$(arg 'v')
75 + #usage To find flag into var: arg f 1 myvar or flag=$(arg 'f')
76 + #usage To echo value: arg v
77 + #usage To echo 1 if flag exists: arg f
78 + argl() {
79 + [ "$1" ] || { echo "Argument name is not specified!" >&2 && exit 1; }
80 + local arg_name="$1" # argument name to find
81 + local is_flag="$2" || 0 # 1 if we need just find a flag, 0 to get a value
82 + local var_name="$3" || 0 # variable name to return value into or 0 to echo it in stdout
83 + local value= # initialize empty value to check if we found one later
84 + local arg_found=0 # marker of found argument
85 +
86 + for idx in "${!__RAW_ARGS__[@]}"; do # going through all args
87 + local arg_search="${__RAW_ARGS__[idx]}" # get current argument
88 +
89 + if [ "$arg_search" = "--$arg_name" ]; then # if current arg begins with two dashes
90 + # then return '1' back into $value if we need flag or next arg value otherwise
91 + [ "$is_flag" = 1 ] && value=1 || value="${__RAW_ARGS__[idx+1]}"
92 + break # stop the loop
93 + elif grep_match "$arg_search" "^--$arg_name=.+$"; then # check if $arg like '--foo=bar'
94 + # then return '1' back into $value if we need flag or part from '=' to arg's end as value otherwise
95 + [ "$is_flag" = 1 ] && value=1 || value="${arg_search#*=}"
96 + break # stop the loop
97 + fi
98 + done
99 +
100 + [ "$is_flag" = 1 ] && [ -z "$value" ] && value=0;
101 +
102 + # if value we found is empty or looks like another argument then exit with error message
103 + if [ "$arg_found" = 1 ] && ! grep_match "$value" "^[[:graph:]]+$" || grep_match "$value" "^--?\w+$"; then
104 + echo "ERROR: Argument '--$arg_name' must have correct value!" >&2 && exit 1;
105 + fi
106 +
107 + # return '$value' back into $var_name (if exists) or echo in stdout
108 + [ "$var_name" ] && eval "$var_name='$value'" || echo "$value"
109 + }
110 +
111 + ################################
112 +
113 + # This is simple examples which you can play around with.
114 + # 1. uncomment code below
115 + # 2. call thi sscript to see what happens:
116 + # /args.sh -abcd --flag1 --flag2 -e evalue -f fvalue --arg1=value1 --arg2 value2
117 +
118 + # __RAW_ARGS__=("$@")
119 +
120 + # arg a 1 flag_a
121 + # echo "Flag -a has value '$flag_a'"
122 + # echo "Flag -a has value '$(arg a 1)'"
123 +
124 + # arg b 1 flag_b
125 + # echo "Flag -b has value '$flag_b'"
126 + # echo "Flag -b has value '$(arg b 1)'"
127 +
128 + # arg c 1 flag_c
129 + # echo "Flag -c has value '$flag_c'"
130 + # echo "Flag -c has value '$(arg c 1)'"
131 +
132 + # arg d 1 flag_d
133 + # echo "Flag -d has value '$flag_d'"
134 + # echo "Flag -d has value '$(arg d 1)'"
135 +
136 + # argl flag1 1 flag_1
137 + # echo "Flag --flag1 has value '$flag_1'"
138 + # echo "Flag --flag1 has value '$(argl flag1 1)'"
139 +
140 + # argl flag2 1 flag_2
141 + # echo "Flag --flag2 has value '$flag_2'"
142 + # echo "Flag --flag2 has value '$(argl flag2 1)'"
143 +
144 + # arg e 0 arg_e
145 + # echo "Arg -e has value '$arg_e'"
146 + # echo "Arg -e has value '$(arg e 0)'"
147 +
148 + # arg f 0 arg_f
149 + # echo "Arg -f has value '$arg_f'"
150 + # echo "Arg -f has value '$(arg f 0)'"
151 +
152 + # argl arg1 0 arg_1
153 + # echo "Arg --arg1 has value '$arg_1'"
154 + # echo "Arg --arg1 has value '$(argl arg1 0)'"
155 +
156 + # argl arg2 0 arg_2
157 + # echo "Arg --arg2 has value '$arg_2'"
158 + # echo "Arg --arg2 has value '$(argl arg2 0)'"
上一页 下一页