|
Packit |
0848f5 |
# -*- mode: sh; -*-
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
# Public domain
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
# Written by Aleksey Cheusov <vle@gmx.net>
|
|
Packit |
0848f5 |
# based on the code from FAQ of comp.unix.shell newsgroup
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
# Set of shell functions for running pipe and checking
|
|
Packit |
0848f5 |
# exit status of ALL programs, not only last one.
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
# Version 0.6.0
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
__shquote (){
|
|
Packit |
0848f5 |
__cmd=`printf '%s\n' "$1" | sed "s|'|'\\\\\''|g"`
|
|
Packit |
0848f5 |
printf "%s\n" "'$__cmd'"
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
__pipestatus_err_msg (){
|
|
Packit |
0848f5 |
if test "$PIPESTATUS_VERBOSE"; then
|
|
Packit |
0848f5 |
echo "Pipe failed, pipestatus_all='$pipestatus_all'" 1>&2
|
|
Packit |
0848f5 |
fi
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# run pipe and set pipestatus_1, pipestatus_2, ... and pipesize variables
|
|
Packit |
0848f5 |
# Example: runpipe_base prog1 arg11 arg12 '|' prog2 arg21 arg22 '|' prog3
|
|
Packit |
0848f5 |
# Always return zero exit status
|
|
Packit |
0848f5 |
runpipe_base (){
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
pipesize=0
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# whole command
|
|
Packit |
0848f5 |
__pipestatus_com=
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# token count
|
|
Packit |
0848f5 |
__pipestatus_k=1
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# program in pipe (between |)
|
|
Packit |
0848f5 |
__pipestatus_l=
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# counter
|
|
Packit |
0848f5 |
__pipestatus_j=1
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# generating whole command
|
|
Packit |
0848f5 |
for __pipestatus_a in "$@"; do
|
|
Packit |
0848f5 |
if [ "_$__pipestatus_a" = '_|' ]; then
|
|
Packit |
0848f5 |
__pipestatus_com="$__pipestatus_com {
|
|
Packit |
0848f5 |
if $__pipestatus_l 3>&-"'; then
|
|
Packit |
0848f5 |
echo "pipestatus_'$__pipestatus_j'=0" 1>&3
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
echo "pipestatus_'$__pipestatus_j'=$?" 1>&3
|
|
Packit |
0848f5 |
fi
|
|
Packit |
0848f5 |
} 4>&- |
|
|
Packit |
0848f5 |
'
|
|
Packit |
0848f5 |
__pipestatus_j=`expr $__pipestatus_j + 1`
|
|
Packit |
0848f5 |
__pipestatus_l=
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
__pipestatus_l="$__pipestatus_l `__shquote \"$__pipestatus_a\"`"
|
|
Packit |
0848f5 |
fi
|
|
Packit |
0848f5 |
__pipestatus_k=`expr $__pipestatus_k + 1`
|
|
Packit |
0848f5 |
done
|
|
Packit |
0848f5 |
__pipestatus_com="if $__pipestatus_com $__pipestatus_l 3>&- 1>&4 4>&-"'; then
|
|
Packit |
0848f5 |
echo "pipestatus_'"$__pipestatus_j"'=0"
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
echo "pipestatus_'"$__pipestatus_j"'=$?"
|
|
Packit |
0848f5 |
fi'
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
# echo "$__pipestatus_com"
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# '|| true' - trick for 'set -e'
|
|
Packit |
0848f5 |
exec 4>&1
|
|
Packit |
0848f5 |
eval `exec 3>&1; eval "$__pipestatus_com" || true`
|
|
Packit |
0848f5 |
exec 4>&-
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#
|
|
Packit |
0848f5 |
pipesize=$__pipestatus_j
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# pipestatus_all
|
|
Packit |
0848f5 |
__pipestatus_j=2
|
|
Packit |
0848f5 |
pipestatus_all=$pipestatus_1
|
|
Packit |
0848f5 |
while [ "$__pipestatus_j" -le "$pipesize" 2>/dev/null ]; do
|
|
Packit |
0848f5 |
eval "pipestatus_all=\"$pipestatus_all \$pipestatus_$__pipestatus_j\""
|
|
Packit |
0848f5 |
__pipestatus_j=`expr $__pipestatus_j + 1`
|
|
Packit |
0848f5 |
done
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return 0
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# returns zero exit status if ALL progs in pipe return zero
|
|
Packit |
0848f5 |
check_status0 (){
|
|
Packit |
0848f5 |
__pipestatus_j=1
|
|
Packit |
0848f5 |
while [ "$__pipestatus_j" -le "$pipesize" ]; do
|
|
Packit |
0848f5 |
eval "[ \$pipestatus_$__pipestatus_j -eq 0 ]" || {
|
|
Packit |
0848f5 |
__pipestatus_err_msg
|
|
Packit |
0848f5 |
return 1
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
__pipestatus_j=`expr $__pipestatus_j + 1`
|
|
Packit |
0848f5 |
done
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return 0
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# returns zero exit status if ALL progs in pipe return zero
|
|
Packit |
0848f5 |
runpipe0 (){
|
|
Packit |
0848f5 |
runpipe_base "$@"
|
|
Packit |
0848f5 |
check_status0
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# match all statuses with the pattern
|
|
Packit |
0848f5 |
# example: check_status_re '0 . 0'
|
|
Packit |
0848f5 |
# . means "any status"
|
|
Packit |
0848f5 |
check_status_re (){
|
|
Packit |
0848f5 |
__pipestatus_re=`echo $1 | sed 's/[.]/[0-9][0-9]*/g'`
|
|
Packit |
0848f5 |
__pipestatus_j=1
|
|
Packit |
0848f5 |
__pipestatus_ps=
|
|
Packit |
0848f5 |
while [ "$__pipestatus_j" -le "$pipesize" ]; do
|
|
Packit |
0848f5 |
eval '__pipestatus_ps="$__pipestatus_ps ${pipestatus_'$__pipestatus_j'}"'
|
|
Packit |
0848f5 |
__pipestatus_j=`expr $__pipestatus_j + 1`
|
|
Packit |
0848f5 |
done
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# trick for set -e
|
|
Packit |
0848f5 |
if echo "$__pipestatus_ps" | grep -E "^ $__pipestatus_re"'$' > /dev/null
|
|
Packit |
0848f5 |
then
|
|
Packit |
0848f5 |
__pipestatus_ret=0
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
__pipestatus_ret=$?
|
|
Packit |
0848f5 |
__pipestatus_err_msg
|
|
Packit |
0848f5 |
fi
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# egrep not found?
|
|
Packit |
0848f5 |
case "$__pipestatus_ret" in
|
|
Packit |
0848f5 |
0|1)
|
|
Packit |
0848f5 |
;;
|
|
Packit |
0848f5 |
*)
|
|
Packit |
0848f5 |
exit 2; # fatal error with egrep
|
|
Packit |
0848f5 |
esac
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return $__pipestatus_ret
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# match all statuses with the pattern
|
|
Packit |
0848f5 |
# example: runpipe_re '0 . 0' prog1 '|' prog2 '|' prog3
|
|
Packit |
0848f5 |
# . means "any status"
|
|
Packit |
0848f5 |
runpipe_re (){
|
|
Packit |
0848f5 |
__pipestatus_re="$1"
|
|
Packit |
0848f5 |
shift
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
runpipe_base "$@"
|
|
Packit |
0848f5 |
check_status_re "$__pipestatus_re"
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# return exit code of the last program in pipe
|
|
Packit |
0848f5 |
check_status (){
|
|
Packit |
0848f5 |
eval return '$pipestatus_'${pipesize}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
# similar to plain pipe but set 'pipestatus_XX' and 'pipesize' variables
|
|
Packit |
0848f5 |
runpipe (){
|
|
Packit |
0848f5 |
runpipe_base "$@"
|
|
Packit |
0848f5 |
check_status
|
|
Packit |
0848f5 |
}
|