| 1 | ## oils_failures_allowed: 5 | 
  | 2 | ## compare_shells: bash mksh ash | 
  | 3 |  | 
  | 4 | # Notes on bash semantics: | 
  | 5 | # | 
  | 6 | # https://www.gnu.org/software/bash/manual/bash.html | 
  | 7 | # | 
  | 8 | # The trap builtin (see Bourne Shell Builtins) allows an ERR pseudo-signal | 
  | 9 | # specification, similar to EXIT and DEBUG. Commands specified with an ERR trap | 
  | 10 | # are executed after a simple command fails, with a few exceptions. The ERR | 
  | 11 | # trap is not inherited by shell functions unless the -o errtrace option to the | 
  | 12 | # set builtin is enabled. | 
  | 13 |  | 
  | 14 |  | 
  | 15 |  | 
  | 16 |  | 
  | 17 | trap 'echo line=$LINENO' ERR | 
  | 18 |  | 
  | 19 | false | 
  | 20 | false | 
  | 21 | echo ok | 
  | 22 |  | 
  | 23 | ## STDOUT: | 
  | 24 | line=3 | 
  | 25 | line=4 | 
  | 26 | ok | 
  | 27 | ## END | 
  | 28 |  | 
  | 29 |  | 
  | 30 |  | 
  | 31 | if test -f /nope; then echo file exists; fi | 
  | 32 |  | 
  | 33 | trap 'echo err' ERR | 
  | 34 | #trap 'echo line=$LINENO' ERR | 
  | 35 |  | 
  | 36 | if test -f /nope; then echo file exists; fi | 
  | 37 |  | 
  | 38 | ## STDOUT: | 
  | 39 | ## END | 
  | 40 |  | 
  | 41 |  | 
  | 42 |  | 
  | 43 | trap 'echo line=$LINENO' ERR | 
  | 44 |  | 
  | 45 | if false; then | 
  | 46 | echo if | 
  | 47 | fi | 
  | 48 |  | 
  | 49 | while false; do | 
  | 50 | echo while | 
  | 51 | done | 
  | 52 |  | 
  | 53 | until false; do | 
  | 54 | echo until | 
  | 55 | break | 
  | 56 | done | 
  | 57 |  | 
  | 58 | false || false || false | 
  | 59 |  | 
  | 60 | false && false && false | 
  | 61 |  | 
  | 62 | false; false; false | 
  | 63 |  | 
  | 64 | echo ok | 
  | 65 |  | 
  | 66 | ## STDOUT: | 
  | 67 | until | 
  | 68 | line=16 | 
  | 69 | line=20 | 
  | 70 | line=20 | 
  | 71 | line=20 | 
  | 72 | ok | 
  | 73 | ## END | 
  | 74 |  | 
  | 75 |  | 
  | 76 |  | 
  | 77 | # mksh and bash have different line numbers in this case | 
  | 78 | trap 'echo err' ERR | 
  | 79 | #trap 'echo line=$LINENO' ERR | 
  | 80 |  | 
  | 81 | # it's run for the last 'false' | 
  | 82 | false | false | false | 
  | 83 |  | 
  | 84 | # it's never run here | 
  | 85 | ! true | 
  | 86 | ! false | 
  | 87 |  | 
  | 88 | ## STDOUT: | 
  | 89 | err | 
  | 90 | ## END | 
  | 91 |  | 
  | 92 |  | 
  | 93 |  | 
  | 94 | trap 'echo line=$LINENO' ERR | 
  | 95 |  | 
  | 96 | f() { | 
  | 97 | false | 
  | 98 | true | 
  | 99 | } | 
  | 100 |  | 
  | 101 | f | 
  | 102 |  | 
  | 103 | ## STDOUT: | 
  | 104 | ## END | 
  | 105 |  | 
  | 106 | ## N-I mksh STDOUT: | 
  | 107 | line=4 | 
  | 108 | ## END | 
  | 109 |  | 
  | 110 |  | 
  | 111 |  | 
  | 112 | trap 'echo line=$LINENO' ERR | 
  | 113 |  | 
  | 114 | passing() { | 
  | 115 | false  # line 4 | 
  | 116 | true | 
  | 117 | } | 
  | 118 |  | 
  | 119 | failing() { | 
  | 120 | true | 
  | 121 | false | 
  | 122 | } | 
  | 123 |  | 
  | 124 | passing | 
  | 125 | failing | 
  | 126 |  | 
  | 127 | set -o errtrace | 
  | 128 |  | 
  | 129 | echo 'now with errtrace' | 
  | 130 | passing | 
  | 131 | failing | 
  | 132 |  | 
  | 133 | echo ok | 
  | 134 |  | 
  | 135 | ## STDOUT: | 
  | 136 | line=14 | 
  | 137 | now with errtrace | 
  | 138 | line=4 | 
  | 139 | line=10 | 
  | 140 | line=20 | 
  | 141 | ok | 
  | 142 | ## END | 
  | 143 |  | 
  | 144 | ## BUG mksh status: 1 | 
  | 145 | ## BUG mksh STDOUT: | 
  | 146 | line=4 | 
  | 147 | line=10 | 
  | 148 | ## END | 
  | 149 |  | 
  | 150 |  | 
  | 151 |  | 
  | 152 |  | 
  | 153 | case $SH in bash|mksh|ash) exit ;; esac | 
  | 154 |  | 
  | 155 | # seems the same | 
  | 156 |  | 
  | 157 | shopt -s ysh:upgrade | 
  | 158 |  | 
  | 159 | proc abc { echo abc } | 
  | 160 | if test -f /nope { echo file exists } | 
  | 161 | trap abc ERR | 
  | 162 | if test -f /nope { echo file exists } | 
  | 163 |  | 
  | 164 | ## STDOUT: | 
  | 165 | abc | 
  | 166 | ## END | 
  | 167 |  | 
  | 168 | ## N-I bash/mksh/ash STDOUT: | 
  | 169 | ## END | 
  | 170 |  | 
  | 171 |  | 
  | 172 | err() { | 
  | 173 | echo "err [$@] $?" | 
  | 174 | } | 
  | 175 | trap 'err x y' ERR | 
  | 176 |  | 
  | 177 | echo A | 
  | 178 |  | 
  | 179 | false | 
  | 180 | echo B | 
  | 181 |  | 
  | 182 | ( exit 42 ) | 
  | 183 | echo C | 
  | 184 |  | 
  | 185 | trap - ERR  # disable trap | 
  | 186 |  | 
  | 187 | false | 
  | 188 | echo D | 
  | 189 |  | 
  | 190 | trap 'echo after errexit $?' ERR | 
  | 191 |  | 
  | 192 | set -o errexit | 
  | 193 |  | 
  | 194 | ( exit 99 ) | 
  | 195 | echo E | 
  | 196 |  | 
  | 197 | ## status: 99 | 
  | 198 | ## STDOUT: | 
  | 199 | A | 
  | 200 | err [x y] 1 | 
  | 201 | B | 
  | 202 | err [x y] 42 | 
  | 203 | C | 
  | 204 | D | 
  | 205 | after errexit 99 | 
  | 206 | ## END | 
  | 207 | ## N-I dash STDOUT: | 
  | 208 | A | 
  | 209 | B | 
  | 210 | C | 
  | 211 | D | 
  | 212 | ## END | 
  | 213 |  | 
  | 214 |  | 
  | 215 | case $SH in ash) exit ;; esac | 
  | 216 |  | 
  | 217 | err() { | 
  | 218 | echo "err [$@] status=$? [${PIPESTATUS[@]}]" | 
  | 219 | } | 
  | 220 | trap 'err' ERR | 
  | 221 |  | 
  | 222 | echo A | 
  | 223 |  | 
  | 224 | false | 
  | 225 |  | 
  | 226 | # succeeds | 
  | 227 | echo B | grep B | 
  | 228 |  | 
  | 229 | # fails | 
  | 230 | echo C | grep zzz | 
  | 231 |  | 
  | 232 | echo D | grep zzz | cat | 
  | 233 |  | 
  | 234 | set -o pipefail | 
  | 235 | echo E | grep zzz | cat | 
  | 236 |  | 
  | 237 | trap - ERR  # disable trap | 
  | 238 |  | 
  | 239 | echo F | grep zz | 
  | 240 | echo ok | 
  | 241 |  | 
  | 242 | ## STDOUT: | 
  | 243 | A | 
  | 244 | err [] status=1 [1] | 
  | 245 | B | 
  | 246 | err [] status=1 [0 1] | 
  | 247 | err [] status=1 [0 1 0] | 
  | 248 | ok | 
  | 249 | ## END | 
  | 250 |  | 
  | 251 | # lastpipe semantics mean we get another call! | 
  | 252 | # also we don't set PIPESTATUS unless we get a pipeline | 
  | 253 |  | 
  | 254 | ## OK osh STDOUT: | 
  | 255 | A | 
  | 256 | err [] status=1 [] | 
  | 257 | B | 
  | 258 | err [] status=1 [0 0] | 
  | 259 | err [] status=1 [0 1] | 
  | 260 | err [] status=1 [0 1 0] | 
  | 261 | ok | 
  | 262 | ## END | 
  | 263 |  | 
  | 264 | ## N-I ash STDOUT: | 
  | 265 | ## END | 
  | 266 |  | 
  | 267 |  | 
  | 268 | case $SH in dash) exit ;; esac | 
  | 269 |  | 
  | 270 | err() { | 
  | 271 | echo err status $? | 
  | 272 | ( exit 2 ) | 
  | 273 | } | 
  | 274 | trap 'err' ERR | 
  | 275 |  | 
  | 276 | echo A | 
  | 277 | false | 
  | 278 | echo B | 
  | 279 |  | 
  | 280 | ## STDOUT: | 
  | 281 | A | 
  | 282 | err status 1 | 
  | 283 | B | 
  | 284 | ## END | 
  | 285 | ## N-I dash STDOUT: | 
  | 286 | ## END | 
  | 287 |  |