8 echo " pipe - mimic pipe(2) syscall in shell"
10 echo " pipe <READER_VAR> <WRITER_VAR>"
12 echo " Create anonymous pipe."
13 echo " Reader end's file descriptor stored in variable name in the first argument."
14 echo " Writer end's file descriptor stored in variable name in the second argument."
16 echo " pipe read_fd write_fd"
17 echo " echo Lorem ipsum >&\$write_fd"
18 echo " read -u \$read_fd data"
19 echo " echo \$data # => Lorem ipsum"
23 local pid1 pid2 myin myout lnk0 lnk1
24 [ "$1" = rdr
] ||
local rdr
25 [ "$2" = wtr
] ||
local wtr
27 myin
=`readlink /proc/self/fd/0`
28 myout
=`readlink /proc/self/fd/1`
30 # calling sleep(1) via env to avoid bash's built-in sleep which may not know 'inf'.
31 env
sleep inf | env
sleep inf
&
37 lnk0
=`readlink /proc/$pid2/fd/0`
38 lnk1
=`readlink /proc/$pid1/fd/1`
39 if [ "$lnk0" != "$myin" -a "$lnk1" != "$myout" ]
45 exec {wtr
}>/proc
/$pid1/fd
/1 {rdr
}</proc
/$pid2/fd
/0
48 kill -KILL $pid1 $pid2 # sometimes INT and TERM are blocked, but it's safe to kill such a no-op process
59 echo " close - mimic close(2) syscall in shell"
61 echo " close <FD_1> [FD_2 [FD_3 [...]]]"
63 echo " Close file descriptor(s) given in arguments."
65 echo " pipe read_fd write_fd"
66 echo " close \$write_fd"
83 echo " capture2 - store a command's stdout and stderr in separated variables"
85 echo " capture2 <COMMAND> [<ARGS>]"
87 echo " Capture <COMMAND>'s stdout and stderr in separated shell variables"
88 echo " without running it twice."
89 echo " Store stdout and stderr data in script-global variables"
90 echo " called \$capture2_stdout and \$capture2_stderr respectively."
92 echo " capture2 ls -lRA /etc"
93 echo " echo output was "'\$capture2_stdout'""
94 echo " echo error was "'\$capture2_stderr'""
96 echo " <COMMAND>'s exit status"
98 echo " using the following script-global variables"
99 echo " - capture2_stdout"
100 echo " - capture2_stderr"
102 echo " May not work on large output, depend on fifo buffer size."
104 echo " pipe(1bash) close(1bash)"
110 capture2_stdout
=$
("$@" 2>&$w)
113 capture2_stderr
=$
(cat <&$r)
120 [ "$1" = 0 -o "$1" = 1 -o "$1" = 2 -o "$1" = 3 -o "$1" = 4 -o "$1" = 5 -o "$1" = 6 -o "$1" = 7 -o "$1" = 8 -o "$1" = 9 ]
125 [ "$1" -ge 0 -o "$1" -lt 0 ] 2>/dev
/null
130 expr "$1" : '[a-zA-Z]\+$' >/dev
/null
2>&1
135 true
"warnx - mimic warnx(3) in shell"
136 echo "${0##*/}: $*" >&2
141 true
"errx - mimic errx(3) in shell"
178 TRYSTACK
+=($
(bash_isset e
$savesets)$
(bash_isset E
$savesets)"$(bash_trapbody ERR)")
189 echo "Unknown option: $1" >&2
204 trydata
=${TRYSTACK[-1]}
205 unset TRYSTACK
[${#TRYSTACK[@]}-1]
206 [ "${trydata:0:1}" = _
] && set +o errexit ||
set -o errexit
207 [ "${trydata:1:1}" = _
] && set +o errtrace ||
set -o errtrace
208 trap "${trydata:2}" ERR
214 ( eval "expr '$-' : '.*e' >/dev/null && set -e; $*"; )
221 local rline tvar var replace sedexpr
226 { grep -Eo '%[a-zA-Z0-9\./_-]+%' <<<"$rline" || true
; } |\
231 # strip percent marks
233 # resolve bash variable
236 replace
=${replace//\\/\\\\}
237 # avoid whole match backref
238 replace
=${replace//&/\\&}
239 # compose sed expression like: s@%user\.name%@joe@g;s@%user\.email%@joe\@local@g;
240 sedexpr
="${sedexpr}s@${tvar//\./\\.}@${replace//@/\@}@g;"
243 sed -e "$sedexpr" <<<"$rline"
268 if [ ".$hay" = ".$needle" ]
281 echo " array_shift - print and remove the first element from a bash indexed array"
283 echo " array_shift <VARNAME>"
285 echo " shoplist=(bread milk sausage)"
286 echo " first_element=\$(array_shift shoplist)"
287 echo " next_element=\$(array_shift shoplist)"
293 eval "aux=\${$array_name[0]}"
295 eval "$array_name=(\"\${$array_name[@]}\")"
304 echo " array_reverse - reverse the order of elements in a bash array in-place"
306 echo " array_reverse <VARNAME>"
314 eval "len=\${#$array_name[@]}"
315 for ((i
=0; i
<len
/2; i
++))
318 eval "aux=\${$array_name[$i]}"
319 eval "$array_name[$i]=\${$array_name[$ci]}"
320 eval "$array_name[$ci]=\$aux"
326 dirname "$(readlink -f "${BASH_SOURCE[-1]}")"
336 # return the canonical form of a version string
338 # trailing ".0" is considered meaningless by SemVer
339 while [[ $ver =~ ^
(.
+)\
.0+$
]]
341 ver
=$
${BASH_REMATCH[1]}
348 # take 2 version numbers (as strings) in arguments, say A and B.
350 # 0 when A equals to B,
351 # 1 when A is greater than B, or
352 # 255 (ie. -1) when A is less than B.
355 ver_a
=`canonize_semver "$ver_a"`
356 ver_b
=`canonize_semver "$ver_b"`
357 if [ "$ver_a" = "$ver_b" ]
361 # feed the 2 version numbers, 1 per line, to sort, then take the first line, which will be the lesser one.
362 local lesser_version
=`echo "$ver_a"$'\n'"$ver_b" | sort --version-sort | sed -ne 1p`
363 if [ "$ver_a" = "$lesser_version" ]
373 version_compare
"$1" "$2"
384 version_compare
"$1" "$2"
393 version_is_greater_or_equal
()
395 ! version_is_lesser
"$@"
398 version_is_lesser_or_equal
()
400 ! version_is_greater
"$@"