File: pipestatus

package info (click to toggle)
mpich 3.3-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 131,836 kB
  • sloc: ansic: 975,868; cpp: 57,437; f90: 53,762; perl: 19,562; xml: 12,464; sh: 12,303; fortran: 7,875; makefile: 7,078; ruby: 126; java: 100; python: 98; lisp: 19; php: 8; sed: 4
file content (164 lines) | stat: -rwxr-xr-x 3,768 bytes parent folder | download | duplicates (3)
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
# -*- mode: sh; -*-

#
# Public domain
#
# Written by Aleksey Cheusov <vle@gmx.net>
# based on the code from FAQ of comp.unix.shell newsgroup
#
# Set of shell functions for running pipe and checking
# exit status of ALL programs, not only last one.
#
# Version 0.6.0
#

# 
__shquote (){
    __cmd=`printf '%s\n' "$1" | sed "s|'|'\\\\\''|g"`
    printf "%s\n" "'$__cmd'"
}

__pipestatus_err_msg (){
    if test "$PIPESTATUS_VERBOSE"; then
	echo "Pipe failed, pipestatus_all='$pipestatus_all'" 1>&2
    fi
}

# run pipe and set pipestatus_1, pipestatus_2, ... and pipesize variables
# Example: runpipe_base prog1 arg11 arg12 '|' prog2 arg21 arg22 '|' prog3
# Always return zero exit status
runpipe_base (){
    #
    pipesize=0

    # whole command
    __pipestatus_com=

    # token count
    __pipestatus_k=1

    # program in pipe (between |)
    __pipestatus_l=

    # counter
    __pipestatus_j=1

    # generating whole command
    for __pipestatus_a in "$@"; do
        if [ "_$__pipestatus_a" = '_|' ]; then
            __pipestatus_com="$__pipestatus_com {
   if $__pipestatus_l 3>&-"'; then
      echo "pipestatus_'$__pipestatus_j'=0" 1>&3
   else
      echo "pipestatus_'$__pipestatus_j'=$?" 1>&3
   fi
} 4>&- |
'
            __pipestatus_j=`expr $__pipestatus_j + 1`
	    __pipestatus_l=
        else
            __pipestatus_l="$__pipestatus_l `__shquote \"$__pipestatus_a\"`"
        fi
        __pipestatus_k=`expr $__pipestatus_k + 1`
    done
    __pipestatus_com="if $__pipestatus_com $__pipestatus_l 3>&- 1>&4 4>&-"'; then
      echo "pipestatus_'"$__pipestatus_j"'=0"
   else
      echo "pipestatus_'"$__pipestatus_j"'=$?"
   fi'

    #
#    echo "$__pipestatus_com"

    # '|| true' - trick for 'set -e'
    exec 4>&1 
    eval `exec 3>&1; eval "$__pipestatus_com" || true`
    exec 4>&- 

    #
    pipesize=$__pipestatus_j

    # pipestatus_all
    __pipestatus_j=2
    pipestatus_all=$pipestatus_1
    while [ "$__pipestatus_j" -le "$pipesize" 2>/dev/null ]; do
	eval "pipestatus_all=\"$pipestatus_all \$pipestatus_$__pipestatus_j\""
        __pipestatus_j=`expr $__pipestatus_j + 1`
    done

    return 0
}

# returns zero exit status if ALL progs in pipe return zero
check_status0 (){
    __pipestatus_j=1
    while [ "$__pipestatus_j" -le "$pipesize" ]; do
	eval "[ \$pipestatus_$__pipestatus_j -eq 0 ]" || {
	    __pipestatus_err_msg
	    return 1
	}
	__pipestatus_j=`expr $__pipestatus_j + 1`
    done

    return 0
}

# returns zero exit status if ALL progs in pipe return zero
runpipe0 (){
    runpipe_base "$@"
    check_status0
}

# match all statuses with the pattern
# example: check_status_re '0 . 0'
# . means "any status"
check_status_re (){
    __pipestatus_re=`echo $1 | sed 's/[.]/[0-9][0-9]*/g'`
    __pipestatus_j=1
    __pipestatus_ps=
    while [ "$__pipestatus_j" -le "$pipesize" ]; do
	eval '__pipestatus_ps="$__pipestatus_ps ${pipestatus_'$__pipestatus_j'}"'
	__pipestatus_j=`expr $__pipestatus_j + 1`
    done

    # trick for set -e
    if echo "$__pipestatus_ps" | grep -E "^ $__pipestatus_re"'$' > /dev/null
    then
	__pipestatus_ret=0
    else
	__pipestatus_ret=$?
	__pipestatus_err_msg
    fi

    # egrep not found?
    case "$__pipestatus_ret" in
	0|1)
	    ;;
	*)
	    exit 2; # fatal error with egrep
    esac

    return $__pipestatus_ret
}

# match all statuses with the pattern
# example: runpipe_re '0 . 0' prog1 '|' prog2 '|' prog3
# . means "any status"
runpipe_re (){
    __pipestatus_re="$1"
    shift

    runpipe_base "$@"
    check_status_re "$__pipestatus_re"
}

# return exit code of the last program in pipe
check_status (){
    eval return '$pipestatus_'${pipesize}
}

# similar to plain pipe but set 'pipestatus_XX' and 'pipesize' variables
runpipe (){
    runpipe_base "$@"
    check_status
}