@renault-digital/bash-base 2.4.1 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/argument.sh CHANGED
@@ -2,7 +2,16 @@
2
2
 
3
3
  source src/constant.sh
4
4
 
5
- THIS_SCRIPT_NAME="$(basename "$0")" # the main script name
5
+ if [[ -n "${ZSH_VERSION:-}" ]]; then
6
+ # zsh may temporarily replace $0 with the sourced filename when
7
+ # FUNCTION_ARGZERO is enabled. ZSH_ARGZERO always keeps the invocation name.
8
+ _bash_base_argzero="${ZSH_ARGZERO:-$0}"
9
+ else
10
+ _bash_base_argzero="$0"
11
+ fi
12
+ THIS_SCRIPT_PATH="$_bash_base_argzero" # script source path for args_valid_* lookup
13
+ THIS_SCRIPT_NAME="$(basename "$_bash_base_argzero")" # the main script name
14
+ unset _bash_base_argzero
6
15
 
7
16
  SHORT_DESC="${THIS_SCRIPT_NAME%%.*}"
8
17
  SHORT_DESC="${SHORT_DESC/[\-_]/ }" # redefine it to show your script short description in the 'NAME' field of generated -h response
@@ -17,9 +26,14 @@ USAGE='' # redefine it in your script only if the gene
17
26
  # @EXAMPLES
18
27
  # args_parse $# "$@" newVar1 newVar2 newVar3
19
28
  # @SEE_ALSO
20
- function args_parse() {
21
- local nbArgValues nbPositionalVarNames option showUsage OPTARG OPTIND nbPositionalArgValues positionalArgValues positionalVarNames
22
- local element validCommand description defaultUsage strPositionalVarNames strPositionalValuesExamples
29
+ args_parse() {
30
+ local nbArgValues nbPositionalVarNames option OPTARG OPTIND nbPositionalArgValues
31
+ local showUsage=false
32
+ local element validCommand description defaultUsage
33
+ local strPositionalVarNames="" strPositionalValuesExamples=""
34
+ local -a positionalArgValues positionalVarNames
35
+ # Bash legacy contract: prompt, possibleValues, i, descriptions and
36
+ # onlyPositionalVarNames were caller-visible, not function-local.
23
37
 
24
38
  nbArgValues=$1
25
39
  shift 1
@@ -42,79 +56,103 @@ function args_parse() {
42
56
  shift $((OPTIND - 1))
43
57
 
44
58
  nbPositionalArgValues=$((nbArgValues - OPTIND + 1))
45
- positionalArgValues=("${@:1:nbPositionalArgValues}")
46
- positionalVarNames=("${@:nbPositionalArgValues+1:nbPositionalVarNames}")
59
+ positionalArgValues=()
60
+ # Split positional values from destination names without a new local
61
+ # counter; the historical Bash `i` global is handled below.
62
+ while (($# > nbPositionalVarNames)); do
63
+ positionalArgValues+=("$1")
64
+ shift
65
+ done
66
+ positionalVarNames=("$@")
47
67
 
48
68
  onlyPositionalVarNames=()
49
69
  descriptions=''
50
- if ((nbPositionalVarNames > 0)); then
51
- for i in $(seq 0 $((nbPositionalVarNames - 1))); do
52
- element=${positionalVarNames[i]}
53
70
 
71
+ # Pair values with variable names without relying on Bash's 0-based array
72
+ # indexes (zsh uses a different default array index base).
73
+ set -- "${positionalArgValues[@]}"
74
+ for element in "${positionalVarNames[@]}"; do
75
+ # Do not introduce a local value variable: callers may legally name
76
+ # their destination positionalValue (or prompt). Save it only in $1.
77
+
78
+ # zsh FUNCTION_ARGZERO may change $0 to the current function name.
79
+ # Only scan a caller script when there is an actual script file.
80
+ validCommand=''
81
+ if [[ -f "${THIS_SCRIPT_PATH:-}" ]]; then
54
82
  validCommand="$(
55
- grep -E "^\s*args_valid.*\s+${element}\s+" "$0" | head -1 |
83
+ grep -E "^[[:space:]]*args_valid.*[[:space:]]+${element}[[:space:]]+" "$THIS_SCRIPT_PATH" | head -1 |
56
84
  awk -F "'" -v OFS="'" '{
57
- for (i=2; i<=NF; i+=2) {
58
- gsub(/ /, "_SPACE_", $i);
59
- gsub(/\$/, "_DOLLAR_", $i);
60
- gsub(/\(/, "_PARENTHESES_LEFT_", $i);
61
- gsub(/\)/, "_PARENTHESES_RIGHT_", $i);
62
- }
63
- print
64
- }' |
85
+ for (i=2; i<=NF; i+=2) {
86
+ gsub(/ /, "_SPACE_", $i);
87
+ gsub(/\$/, "_DOLLAR_", $i);
88
+ gsub(/\(/, "_PARENTHESES_LEFT_", $i);
89
+ gsub(/\)/, "_PARENTHESES_RIGHT_", $i);
90
+ }
91
+ print
92
+ }' |
65
93
  sed -e "s/\'//g"
66
94
  )"
95
+ fi
67
96
 
68
- if [[ -z ${validCommand} ]]; then
69
- eval "${positionalVarNames[i]}='${positionalArgValues[i]}'"
97
+ if [[ -z $validCommand ]]; then
98
+ eval "${element}=\"\${1-}\""
99
+ onlyPositionalVarNames+=("${element}")
100
+ description="a valid value for ${element}"
101
+ else
102
+ if [[ "$validCommand" == *args_valid_or_select_pipe* ]]; then
103
+ eval "${element}=\"\${1-}\""
104
+ onlyPositionalVarNames+=("${element}")
105
+ prompt="$(reflect_nth_arg 4 "$validCommand")"
106
+ possibleValues=", possible values: $(reflect_nth_arg 3 "$validCommand")"
107
+ elif [[ "$validCommand" == *args_valid_or_select_args* ]]; then
108
+ eval "${element}=\"\${1-}\""
109
+ onlyPositionalVarNames+=("${element}")
110
+ prompt="$(reflect_nth_arg 3 "$validCommand")"
111
+ possibleValues=", you can select one using wizard if you do not know which value is valid"
112
+ elif [[ "$validCommand" == *args_valid_or_select* ]]; then
113
+ eval "${element}=\"\${1-}\""
70
114
  onlyPositionalVarNames+=("${element}")
71
- description="a valid value for ${element}"
72
- else
73
- if [[ "${validCommand}" =~ 'args_valid_or_select_pipe' ]]; then
74
- eval "${positionalVarNames[i]}='${positionalArgValues[i]}'"
75
- onlyPositionalVarNames+=("${element}")
76
- prompt="$(reflect_nth_arg 4 "${validCommand}")"
77
- possibleValues=", possible values: $(reflect_nth_arg 3 "$validCommand")"
78
- elif [[ "${validCommand}" =~ 'args_valid_or_select_args' ]]; then
79
- eval "${positionalVarNames[i]}='${positionalArgValues[i]}'"
80
- onlyPositionalVarNames+=("${element}")
81
- prompt="$(reflect_nth_arg 3 "${validCommand}")"
82
- possibleValues=", you can select one using wizard if you do not know which value is valid"
83
- elif [[ "${validCommand}" =~ 'args_valid_or_select' ]]; then
84
- eval "${positionalVarNames[i]}='${positionalArgValues[i]}'"
85
- onlyPositionalVarNames+=("${element}")
86
- prompt="$(reflect_nth_arg 4 "${validCommand}")"
87
- possibleValues=", you can select one using wizard if you do not know which value is valid"
88
- elif [[ "${validCommand}" =~ args_valid_or_read ]]; then
89
- eval "${positionalVarNames[i]}='${positionalArgValues[i]}'"
90
- onlyPositionalVarNames+=("${element}")
91
- prompt="$(reflect_nth_arg 4 "${validCommand}")"
92
- if [[ -n $(reflect_nth_arg 5 "${validCommand}") ]]; then
93
- prompt="${prompt}, proposed value: $(reflect_nth_arg 5 "${validCommand}")"
94
- fi
95
- possibleValues=""
96
- elif [[ "${validCommand}" =~ args_valid_or_default ]]; then
97
- prompt="optional, $(reflect_nth_arg 4 "${validCommand}"). should be set like '${element}=value' before ${THIS_SCRIPT_NAME} or export to OS environment"
98
- if [[ -n $(reflect_nth_arg 5 "${validCommand}") ]]; then
99
- prompt="${prompt}. if absent, fallback to: $(reflect_nth_arg 5 "${validCommand}")"
100
- else
101
- prompt="${prompt}, empty if absent"
102
- fi
103
- possibleValues=""
115
+ prompt="$(reflect_nth_arg 4 "$validCommand")"
116
+ possibleValues=", you can select one using wizard if you do not know which value is valid"
117
+ elif [[ "$validCommand" == *args_valid_or_read* ]]; then
118
+ eval "${element}=\"\${1-}\""
119
+ onlyPositionalVarNames+=("${element}")
120
+ prompt="$(reflect_nth_arg 4 "$validCommand")"
121
+ if [[ -n $(reflect_nth_arg 5 "$validCommand") ]]; then
122
+ prompt="${prompt}, proposed value: $(reflect_nth_arg 5 "$validCommand")"
123
+ fi
124
+ possibleValues=""
125
+ elif [[ "$validCommand" == *args_valid_or_default* ]]; then
126
+ prompt="optional, $(reflect_nth_arg 4 "$validCommand"). should be set like ${element}=value before ${THIS_SCRIPT_NAME} or export to OS environment"
127
+ if [[ -n $(reflect_nth_arg 5 "$validCommand") ]]; then
128
+ prompt="${prompt}. if absent, fallback to: $(reflect_nth_arg 5 "$validCommand")"
129
+ else
130
+ prompt="${prompt}, empty if absent"
104
131
  fi
132
+ possibleValues=""
133
+ fi
105
134
 
106
- prompt="$(
107
- echo "${prompt}" |
108
- string_replace "_SPACE_" " " |
109
- string_replace "_DOLLAR_" "$" |
110
- string_replace "_PARENTHESES_LEFT_" "(" |
111
- string_replace "_PARENTHESES_RIGHT_" ")"
112
- )"
135
+ prompt="$(
136
+ printf '%s\n' "${prompt}" |
137
+ string_replace "_SPACE_" " " |
138
+ string_replace "_DOLLAR_" "$" |
139
+ string_replace "_PARENTHESES_LEFT_" "(" |
140
+ string_replace "_PARENTHESES_RIGHT_" ")"
141
+ )"
113
142
 
114
- description="${prompt}${possibleValues}"
115
- fi
116
- descriptions+="$(printf "\n %-20s%s" "${element} " "${description}")"
117
- done
143
+ description="${prompt}${possibleValues}"
144
+ fi
145
+ descriptions+="$(printf "\n %-20s%s" "${element} " "${description}")"
146
+ if (($# > 0)); then
147
+ shift
148
+ fi
149
+ done
150
+ if [[ -n "${BASH_VERSION:-}" && $nbPositionalVarNames -gt 0 ]]; then
151
+ # The original Bash implementation used a caller-visible `i` as
152
+ # a loop counter over output names. Respect a destination named i.
153
+ if ! array_in i "${positionalVarNames[@]}"; then
154
+ i=$((nbPositionalVarNames - 1))
155
+ fi
118
156
  fi
119
157
 
120
158
  if [ ${#onlyPositionalVarNames[@]} -gt 0 ]; then
@@ -122,36 +160,36 @@ function args_parse() {
122
160
  strPositionalValuesExamples=" \"$(array_join 'Value" "' onlyPositionalVarNames)Value\""
123
161
  fi
124
162
 
125
- declare_heredoc defaultUsage <<-EOF
126
- ${COLOR_BOLD_YELLOW}NAME${COLOR_END}
127
- ${THIS_SCRIPT_NAME} -- ${SHORT_DESC}
163
+ declare_heredoc defaultUsage <<EOF
164
+ ${COLOR_BOLD_YELLOW}NAME${COLOR_END}
165
+ ${THIS_SCRIPT_NAME} -- ${SHORT_DESC}
128
166
 
129
- ${COLOR_BOLD_YELLOW}SYNOPSIS${COLOR_END}
130
- [optionalVariable=value ...] ./${THIS_SCRIPT_NAME} [-qh]${strPositionalVarNames}
167
+ ${COLOR_BOLD_YELLOW}SYNOPSIS${COLOR_END}
168
+ [optionalVariable=value ...] ./${THIS_SCRIPT_NAME} [-qh]${strPositionalVarNames}
131
169
 
132
- ${COLOR_BOLD_YELLOW}DESCRIPTION${COLOR_END}
133
- [-h] help, print the usage
134
- [-q] optional, Run quietly, no confirmation
135
- ${descriptions}
170
+ ${COLOR_BOLD_YELLOW}DESCRIPTION${COLOR_END}
171
+ [-h] help, print the usage
172
+ [-q] optional, Run quietly, no confirmation
173
+ ${descriptions}
136
174
 
137
- ${COLOR_BOLD_YELLOW}EXAMPLES${COLOR_END}
138
- help, print the usage:
139
- ./${THIS_SCRIPT_NAME} -h
175
+ ${COLOR_BOLD_YELLOW}EXAMPLES${COLOR_END}
176
+ help, print the usage:
177
+ ./${THIS_SCRIPT_NAME} -h
140
178
 
141
- run with all params, if run in quiet mode with -q, be sure all the params are valid:
142
- ./${THIS_SCRIPT_NAME} [-q]${strPositionalValuesExamples}
179
+ run with all params, if run in quiet mode with -q, be sure all the params are valid:
180
+ ./${THIS_SCRIPT_NAME} [-q]${strPositionalValuesExamples}
143
181
 
144
- run using wizard, input value for params step by step:
145
- ./${THIS_SCRIPT_NAME}
182
+ run using wizard, input value for params step by step:
183
+ ./${THIS_SCRIPT_NAME}
146
184
 
147
- run with optional variables, example:
148
- myOpt1=myValue1 myOpt2=myValue2 ./${THIS_SCRIPT_NAME}
185
+ run with optional variables, example:
186
+ myOpt1=myValue1 myOpt2=myValue2 ./${THIS_SCRIPT_NAME}
149
187
 
150
- or you can run with some params, and input value for other params using wizard.
151
- EOF
188
+ or you can run with some params, and input value for other params using wizard.
189
+ EOF
152
190
 
153
- if [ "$showUsage" == true ]; then
154
- echo -e "${USAGE:-$defaultUsage}"
191
+ if [[ "$showUsage" == true ]]; then
192
+ printf '%b\n' "${USAGE:-$defaultUsage}"
155
193
  exit 0
156
194
  fi
157
195
  }
@@ -172,26 +210,38 @@ function args_parse() {
172
210
  # args_valid_or_select varEmpty arr "Which app"
173
211
  # @SEE_ALSO
174
212
  # args_valid_or_select_pipe, args_valid_or_read, args_valid_or_default
175
- function args_valid_or_select() {
176
- local valueVarName validValuesVarName prompt value validValues PS3
213
+ args_valid_or_select() {
214
+ local valueVarName validValuesVarName prompt value PS3
215
+ local -a validValues
216
+
177
217
  valueVarName="${1}"
178
- validValuesVarName=$2
179
- validValues="$2[@]"
218
+ validValuesVarName="$2"
180
219
  prompt="${3}"
181
-
182
- value=$(eval eval "echo '$'${valueVarName}")
220
+ eval 'value="${'"$valueVarName"'-}"'
221
+ if [[ -n "${BASH_VERSION:-}" ]]; then
222
+ # Preserve Bash's historical echo/word-splitting normalization, without
223
+ # reparsing the value with eval (which would execute input as code).
224
+ # shellcheck disable=SC2086,SC2116
225
+ value="$(echo $value)"
226
+ fi
227
+ eval "validValues=( \"\${${validValuesVarName}[@]}\" )"
183
228
 
184
229
  while ! array_contains "${validValuesVarName}" "${value}"; do
185
- echo -e "\n${prompt} ?"
230
+ printf '\n%s ?\n' "$prompt"
186
231
  [[ -n "${value}" ]] && print_error "the input '${value}' is not valid."
187
232
 
188
233
  PS3="choose one by ${COLOR_BOLD_YELLOW}number${COLOR_END} [1|2|...] ? "
189
- select value in "${!validValues}"; do
234
+ select value in "${validValues[@]}"; do
190
235
  break
191
236
  done
192
237
  done
193
- eval "${valueVarName}='${value}'"
194
- printf "Selected value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(eval echo '$'"${valueVarName}")"
238
+
239
+ eval "${valueVarName}=\"\$value\""
240
+ if [[ -n "${BASH_VERSION:-}" ]]; then
241
+ # shellcheck disable=SC2086,SC2116
242
+ value="$(echo $value)"
243
+ fi
244
+ printf "Selected value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
195
245
  }
196
246
 
197
247
  # @NAME
@@ -207,8 +257,9 @@ function args_valid_or_select() {
207
257
  # args_valid_or_select_pipe sel "a|ab|d" "which value"
208
258
  # @SEE_ALSO
209
259
  # args_valid_or_select, args_valid_or_select_args, args_valid_or_read, args_valid_or_default
210
- function args_valid_or_select_pipe() {
211
- local valueVarName validValues prompt newArray
260
+ args_valid_or_select_pipe() {
261
+ local valueVarName validValues prompt
262
+ local -a newArray
212
263
  valueVarName="${1}"
213
264
  validValues="${2}"
214
265
  prompt="${3}"
@@ -230,15 +281,21 @@ function args_valid_or_select_pipe() {
230
281
  # args_valid_or_select_args sel "which value" "a" "ab" "d"
231
282
  # @SEE_ALSO
232
283
  # args_valid_or_select, args_valid_or_select_pipe, args_valid_or_read, args_valid_or_default
233
- function args_valid_or_select_args() {
284
+ args_valid_or_select_args() {
234
285
  local valueVarName value prompt PS3
235
286
  valueVarName="${1}"
236
- value=$(eval eval "echo '$'${valueVarName}")
287
+ eval 'value="${'"$valueVarName"'-}"'
288
+ if [[ -n "${BASH_VERSION:-}" ]]; then
289
+ # Preserve Bash's historical echo/word-splitting normalization, without
290
+ # reparsing the value with eval (which would execute input as code).
291
+ # shellcheck disable=SC2086,SC2116
292
+ value="$(echo $value)"
293
+ fi
237
294
  prompt="${2}"
238
295
  shift 2
239
296
 
240
297
  while ! array_in "${value}" "$@"; do
241
- echo -e "\n${prompt} ?"
298
+ printf '\n%s ?\n' "$prompt"
242
299
  [[ -n "${value}" ]] && print_error "the input '${value}' is not valid."
243
300
 
244
301
  PS3="choose one by ${COLOR_BOLD_YELLOW}number${COLOR_END} [1|2|...] ? "
@@ -246,8 +303,13 @@ function args_valid_or_select_args() {
246
303
  break
247
304
  done
248
305
  done
249
- eval "${valueVarName}='${value}'"
250
- printf "Selected value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(eval echo '$'"${valueVarName}")"
306
+
307
+ eval "${valueVarName}=\"\$value\""
308
+ if [[ -n "${BASH_VERSION:-}" ]]; then
309
+ # shellcheck disable=SC2086,SC2116
310
+ value="$(echo $value)"
311
+ fi
312
+ printf "Selected value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
251
313
  }
252
314
 
253
315
  # @NAME
@@ -265,28 +327,48 @@ function args_valid_or_select_args() {
265
327
  # args_valid_or_read destRootPackage '^.+$' "Destination root package" "${defaultDestRootPackage}"
266
328
  # @SEE_ALSO
267
329
  # args_valid_or_select, args_valid_or_select_args, args_valid_or_select_pipe, args_valid_or_default
268
- function args_valid_or_read() {
269
- local value regExp prompt proposedValue
270
- value=$(eval eval "echo '$'$1")
271
- regExp=${2}
272
- prompt="${3}"
273
- proposedValue="${4}"
330
+ args_valid_or_read() {
331
+ local valueVarName="$1"
332
+ local regExp="${2}"
333
+ local prompt="${3}"
334
+ local proposedValue="${4-}"
335
+ local value
336
+
337
+ eval 'value="${'"$valueVarName"'-}"'
338
+ if [[ -n "${BASH_VERSION:-}" ]]; then
339
+ # Preserve Bash's historical echo/word-splitting normalization, without
340
+ # reparsing the value with eval (which would execute input as code).
341
+ # shellcheck disable=SC2086,SC2116
342
+ value="$(echo $value)"
343
+ fi
274
344
 
275
345
  if [[ -n "${proposedValue}" ]]; then
276
346
  prompt="${prompt} [${proposedValue}]"
277
- if [[ -z "${value}" && "${modeQuiet}" == true ]]; then
347
+ if [[ -z "${value}" && "${modeQuiet:-false}" == true ]]; then
278
348
  value="${proposedValue}"
279
349
  fi
280
350
  fi
281
- while ! [[ ${value} =~ ${regExp} ]]; do
351
+
352
+ while ! [[ $value =~ $regExp ]]; do
282
353
  [[ -n "${value}" ]] && print_error "the input '${value}' is not valid, please input again."
283
- read -r -p "${prompt}: " value
354
+ if [[ -t 0 ]]; then
355
+ printf '%s: ' "$prompt" >&2
356
+ fi
357
+ read -r value || value=""
284
358
  if [[ -z "${value}" ]]; then
285
359
  value="${proposedValue}"
286
360
  fi
287
361
  done
288
- eval "${1}='${value}'"
289
- printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(eval echo '$'"${1}")"
362
+
363
+ eval "${valueVarName}=\"\$value\""
364
+ if [[ -n "${BASH_VERSION:-}" ]]; then
365
+ # Legacy Bash printed via `eval echo $name`: collapse display-only
366
+ # whitespace, but leave the actual assigned value unchanged.
367
+ # shellcheck disable=SC2086,SC2116
368
+ printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(echo $value)"
369
+ else
370
+ printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
371
+ fi
290
372
  }
291
373
 
292
374
  # @NAME
@@ -307,20 +389,36 @@ function args_valid_or_read() {
307
389
  # args_valid_or_default destRootPackage '^.+$' "Destination root package" "${defaultDestRootPackage}"
308
390
  # @SEE_ALSO
309
391
  # args_valid_or_select, args_valid_or_select_args, args_valid_or_select_pipe, args_valid_or_read
310
- function args_valid_or_default() {
311
- local value regExp prompt defaultValue
312
- value=$(eval eval "echo '$'$1")
313
- regExp=${2}
314
- prompt="${3}"
315
- defaultValue="${4}"
392
+ args_valid_or_default() {
393
+ local valueVarName="$1"
394
+ local regExp="${2}"
395
+ local prompt="${3}"
396
+ local defaultValue="${4-}"
397
+ local value
398
+
399
+ eval 'value="${'"$valueVarName"'-}"'
400
+ if [[ -n "${BASH_VERSION:-}" ]]; then
401
+ # Preserve Bash's historical echo/word-splitting normalization, without
402
+ # reparsing the value with eval (which would execute input as code).
403
+ # shellcheck disable=SC2086,SC2116
404
+ value="$(echo $value)"
405
+ fi
316
406
 
317
- if [[ -z "${value}" || ! ${value} =~ ${regExp} ]]; then
318
- prompt="for param ${1}:"
407
+ if [[ -z "${value}" || ! $value =~ $regExp ]]; then
408
+ prompt="for param ${valueVarName}:"
319
409
  [[ -n "${value}" ]] && prompt+=" the input '${value}' is not valid" || prompt+=" no input"
320
410
  [[ -n "${defaultValue}" ]] && prompt+=", fallback to default value '${defaultValue}'" || prompt+=", fallback to empty"
321
411
  print_warn "${prompt}"
322
412
  value="${defaultValue}"
323
413
  fi
324
- eval "${1}='${value}'"
325
- printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(eval echo '$'"${1}")"
414
+
415
+ eval "${valueVarName}=\"\$value\""
416
+ if [[ -n "${BASH_VERSION:-}" ]]; then
417
+ # Legacy Bash printed via `eval echo $name`: collapse display-only
418
+ # whitespace, but leave the actual assigned value unchanged.
419
+ # shellcheck disable=SC2086,SC2116
420
+ printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(echo $value)"
421
+ else
422
+ printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
423
+ fi
326
424
  }