1 # Oil xtrace
2
3 #### Customize PS4
4 shopt -s oil:upgrade
5 set -x
6
7 # Reuse the default
8 PS4='$LINENO '"$PS4"
9 echo 1; echo 2
10 echo 3
11 ## STDOUT:
12 1
13 2
14 3
15 ## END
16 ## STDERR:
17 5 . builtin echo 1
18 5 . builtin echo 2
19 6 . builtin echo 3
20 ## END
21
22
23 #### xtrace_details doesn't show [[ ]] etc.
24 shopt -s oil:upgrade
25 set -x
26
27 dir=/
28 if [[ -d $dir ]]; then
29 (( a = 42 ))
30 fi
31 cd /
32
33 ## stdout-json: ""
34 ## STDERR:
35 . builtin cd /
36 ## END
37
38 #### xtrace_details AND xtrace_rich on
39 shopt -s oil:upgrade xtrace_details
40 shopt --unset errexit
41 set -x
42
43 {
44 env false
45 set +x
46 } 2>err.txt
47
48 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
49
50 ## STDOUT:
51 ## END
52 ## STDERR:
53 | command 12345: env 'false'
54 ; process 12345: status 1
55 . builtin set '+x'
56 ## END
57
58 #### proc and shell function
59 shopt --set ysh:upgrade
60 set -x
61
62 shfunc() {
63 : $1
64 }
65
66 proc p (x) {
67 : $x
68 }
69
70 shfunc 1
71 p 2
72 ## stdout-json: ""
73 ## STDERR:
74 > proc shfunc 1
75 . builtin ':' 1
76 < proc shfunc
77 > proc p 2
78 . builtin ':' 2
79 < proc p
80 ## END
81
82 #### eval
83 shopt --set oil:upgrade
84 set -x
85
86 eval 'echo 1; echo 2'
87 ## STDOUT:
88 1
89 2
90 ## END
91 ## STDERR:
92 > eval
93 . builtin echo 1
94 . builtin echo 2
95 < eval
96 ## END
97
98 #### source
99 echo 'echo "\$1 = $1"' > lib.sh
100
101 shopt --set oil:upgrade
102 set -x
103
104 source lib.sh a b c
105
106 # Test the quoting style. TODO: Don't use bash style in YSH.
107
108 source lib.sh x $'\xfe' $'\xff'
109
110 ## STDOUT:
111 $1 = a
112 $1 = x
113 ## END
114 ## STDERR:
115 > source lib.sh a b c
116 . builtin echo '$1 = a'
117 < source lib.sh
118 > source lib.sh x $'\xfe' $'\xff'
119 . builtin echo '$1 = x'
120 < source lib.sh
121 ## END
122
123 #### external and builtin
124 shopt --set oil:upgrade
125 shopt --unset errexit
126 set -x
127
128 {
129 env false
130 true
131 set +x
132 } 2>err.txt
133
134 # normalize PIDs, assumed to be 2 or more digits
135 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
136
137 ## stdout-json: ""
138 ## STDERR:
139 | command 12345: env 'false'
140 ; process 12345: status 1
141 . builtin 'true'
142 . builtin set '+x'
143 ## END
144
145 #### subshell
146 shopt --set oil:upgrade
147 shopt --unset errexit
148 set -x
149
150 proc p {
151 : p
152 }
153
154 {
155 : begin
156 (
157 : 1
158 p
159 exit 3
160 )
161 set +x
162 } 2>err.txt
163
164 # Hack: sort for determinism
165 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt | LANG=C sort >&2
166
167 ## stdout-json: ""
168 ## STDERR:
169 . 12345 builtin ':' p
170 + 12345 exit 3
171 . 12345 builtin ':' 1
172 < 12345 proc p
173 > 12345 proc p
174 . builtin ':' begin
175 . builtin set '+x'
176 ; process 12345: status 3
177 | forkwait 12345
178 ## END
179
180 #### command sub
181 shopt --set oil:upgrade
182 set -x
183
184 {
185 echo foo=$(echo bar)
186 set +x
187
188 } 2>err.txt
189
190 # HACK: sort because xtrace output has non-determinism.
191 # This is arguably a bug -- see issue #995.
192 # The real fix might be to sys.stderr.flush() in few places?
193 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt | LANG=C sort >&2
194
195 ## STDOUT:
196 foo=bar
197 ## END
198 ## STDERR:
199 . 12345 builtin echo bar
200 . builtin echo 'foo=bar'
201 . builtin set '+x'
202 ; process 12345: status 0
203 | command sub 12345
204 ## END
205
206 #### process sub (nondeterministic)
207 shopt --set oil:upgrade
208 shopt --unset errexit
209 set -x
210
211 # we wait() for them all at the end
212
213 {
214 : begin
215 cat <(seq 2) <(echo 1)
216 set +x
217 } 2>err.txt
218
219 # SORT for determinism
220 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g; s|/fd/.|/fd/N|g' err.txt |
221 LC_ALL=C sort >&2
222 #cat err.txt >&2
223
224 ## STDOUT:
225 1
226 2
227 1
228 ## END
229
230 ## STDERR:
231 . 12345 builtin echo 1
232 ; 12345 process 12345: status 0
233 | 12345 command 12345: seq 2
234 . builtin ':' begin
235 . builtin set '+x'
236 ; process 12345: status 0
237 ; process 12345: status 0
238 ; process 12345: status 0
239 | command 12345: cat /dev/fd/N /dev/fd/N
240 | proc sub 12345
241 | proc sub 12345
242 ## END
243
244 #### pipeline (nondeterministic)
245 shopt --set oil:upgrade
246 set -x
247
248 myfunc() {
249 echo 1
250 echo 2
251 }
252
253 {
254 : begin
255 myfunc | sort | wc -l
256 set +x
257 } 2>err.txt
258
259 do_sort=1
260
261 if test -n $do_sort; then
262 # SORT for determinism
263 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g; s|/fd/.|/fd/N|g' err.txt |
264 LC_ALL=C sort >&2
265 else
266 cat err.txt
267 fi
268
269 ## STDOUT:
270 2
271 ## END
272 ## STDERR:
273 . 12345 builtin echo 1
274 . 12345 builtin echo 2
275 ; 12345 process 12345: status 0
276 < 12345 proc myfunc
277 > 12345 proc myfunc
278 | 12345 command 12345: sort
279 ; process 12345: status 0
280 ; process 12345: status 0
281 ; process 12345: status 0
282 | command 12345: wc -l
283 | part 12345
284 | part 12345
285 . builtin ':' begin
286 . builtin set '+x'
287 < pipeline
288 > pipeline
289 ## END
290
291 #### singleton pipeline
292
293 # Hm extra tracing
294
295 shopt --set oil:upgrade
296 set -x
297
298 : begin
299 ! false
300 : end
301
302 ## stdout-json: ""
303 ## STDERR:
304 . builtin ':' begin
305 . builtin 'false'
306 . builtin ':' end
307 ## END
308
309 #### Background pipeline (separate code path)
310
311 shopt --set oil:upgrade
312 shopt --unset errexit
313 set -x
314
315 myfunc() {
316 echo 2
317 echo 1
318 }
319
320 {
321 : begin
322 myfunc | sort | grep ZZZ &
323 wait
324 echo status=$?
325 set +x
326 } 2>err.txt
327
328 # SORT for determinism
329 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt |
330 LC_ALL=C sort >&2
331
332 ## STDOUT:
333 status=0
334 ## END
335 ## STDERR:
336 . 12345 builtin echo 1
337 . 12345 builtin echo 2
338 ; 12345 process 12345: status 0
339 ; 12345 process 12345: status 1
340 ; process 12345: status 0
341 ; process 12345: status 0
342 ; process 12345: status 1
343 < 12345 proc myfunc
344 > 12345 proc myfunc
345 | 12345 command 12345: grep ZZZ
346 | 12345 command 12345: sort
347 . builtin ':' begin
348 . builtin echo 'status=0'
349 . builtin set '+x'
350 < wait
351 > wait
352 [1] Done PGID 12345
353 | part 12345
354 | part 12345
355 | part 12345
356 ## END
357
358 #### Background process with fork and & (nondeterministic)
359 shopt --set oil:upgrade
360 set -x
361
362 {
363 sleep 0.1 &
364 wait
365
366 shopt -s oil:upgrade
367
368 fork {
369 sleep 0.1
370 }
371 wait
372 set +x
373 } 2>err.txt
374
375 # SORT for determinism
376 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt |
377 LC_ALL=C sort >&2
378
379 ## stdout-json: ""
380 ## STDERR:
381 ; 12345 process 12345: status 0
382 ; 12345 process 12345: status 0
383 ; process 12345: status 0
384 ; process 12345: status 0
385 | 12345 command 12345: sleep 0.1
386 | 12345 command 12345: sleep 0.1
387 . builtin fork
388 . builtin set '+x'
389 . builtin shopt -s 'oil:upgrade'
390 < wait
391 < wait
392 > wait
393 > wait
394 [1] Done PID 12345
395 [1] Done PID 12345
396 | fork 12345
397 | fork 12345
398 ## END
399
400 # others: redirects?
401
402 #### Here doc
403 shopt --set ysh:upgrade
404 shopt --unset errexit
405 set -x
406
407 {
408 : begin
409 tac <<EOF
410 3
411 2
412 EOF
413
414 set +x
415 } 2>err.txt
416
417 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
418
419 ## STDOUT:
420 2
421 3
422 ## END
423 ## STDERR:
424 . builtin ':' begin
425 | command 12345: tac
426 ; process 12345: status 0
427 . builtin set '+x'
428 ## END
429
430 #### Two here docs
431
432 # BUG: This trace shows an extra process?
433
434 shopt --set ysh:upgrade
435 shopt --unset errexit
436 set -x
437
438 {
439 cat - /dev/fd/3 <<EOF 3<<EOF2
440 xx
441 yy
442 EOF
443 zz
444 EOF2
445
446 set +x
447 } 2>err.txt
448
449 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
450
451 ## STDOUT:
452 xx
453 yy
454 zz
455 ## END
456 ## STDERR:
457 | command 12345: cat - /dev/fd/3
458 ; process 12345: status 0
459 . builtin set '+x'
460 ## END
461
462 #### Here doc greater than 4096 bytes
463
464 {
465 echo 'wc -l <<EOF'
466 seq 2000
467 echo 'EOF'
468 } > big-here.sh
469
470 wc -l big-here.sh
471
472 $SH -o ysh:upgrade -x big-here.sh 2>err.txt
473
474 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
475
476 ## STDOUT:
477 2002 big-here.sh
478 2000
479 ## END
480 ## STDERR:
481 | here doc 12345
482 | command 12345: wc -l
483 ; process 12345: status 0
484 ; process 12345: status 0
485 ## END
486
487 #### Control Flow
488 shopt --set oil:upgrade
489 set -x
490
491 for i in 1 2 3 {
492 echo $i
493 if (i === '2') {
494 break
495 }
496 }
497
498 for j in a b {
499 for k in y z {
500 echo $j $k
501 if (k === 'y') {
502 continue
503 }
504 }
505 }
506
507 proc zero {
508 return 0
509 }
510
511 proc one {
512 return 1
513 }
514
515 zero
516 # one
517
518 ## STDOUT:
519 1
520 2
521 a y
522 a z
523 b y
524 b z
525 ## END
526 ## STDERR:
527 . builtin echo 1
528 . builtin echo 2
529 + break 1
530 . builtin echo a y
531 + continue 1
532 . builtin echo a z
533 . builtin echo b y
534 + continue 1
535 . builtin echo b z
536 > proc zero
537 + return 0
538 < proc zero
539 ## END
540
541 #### Encoded argv uses shell encoding, not J8
542
543 shopt --set ysh:upgrade
544 set -x
545
546 echo $'one two\n' $'\u03bc'
547 ## STDOUT:
548 one two
549 μ
550 ## END
551 ## STDERR:
552 . builtin echo $'one two\n' 'μ'
553 ## END