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 exec seq 2
233 . builtin ':' begin
234 . builtin set '+x'
235 ; process 12345: status 0
236 ; process 12345: status 0
237 ; process 12345: status 0
238 | command 12345: cat /dev/fd/N /dev/fd/N
239 | proc sub 12345
240 | proc sub 12345
241 ## END
242
243 #### pipeline (nondeterministic)
244 shopt --set oil:upgrade
245 set -x
246
247 myfunc() {
248 echo 1
249 echo 2
250 }
251
252 {
253 : begin
254 myfunc | sort | wc -l
255 set +x
256 } 2>err.txt
257
258 do_sort=1
259
260 if test -n $do_sort; then
261 # SORT for determinism
262 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g; s|/fd/.|/fd/N|g' err.txt |
263 LC_ALL=C sort >&2
264 else
265 cat err.txt
266 fi
267
268 ## STDOUT:
269 2
270 ## END
271 ## STDERR:
272 . 12345 builtin echo 1
273 . 12345 builtin echo 2
274 . 12345 exec sort
275 < 12345 proc myfunc
276 > 12345 proc myfunc
277 ; process 12345: status 0
278 ; process 12345: status 0
279 ; process 12345: status 0
280 | command 12345: wc -l
281 | part 12345
282 | part 12345
283 . builtin ':' begin
284 . builtin set '+x'
285 < pipeline
286 > pipeline
287 ## END
288
289 #### singleton pipeline
290
291 # Hm extra tracing
292
293 shopt --set oil:upgrade
294 set -x
295
296 : begin
297 ! false
298 : end
299
300 ## stdout-json: ""
301 ## STDERR:
302 . builtin ':' begin
303 . builtin 'false'
304 . builtin ':' end
305 ## END
306
307 #### Background pipeline (separate code path)
308
309 shopt --set oil:upgrade
310 shopt --unset errexit
311 set -x
312
313 myfunc() {
314 echo 2
315 echo 1
316 }
317
318 {
319 : begin
320 myfunc | sort | grep ZZZ &
321 wait
322 echo status=$?
323 set +x
324 } 2>err.txt
325
326 # SORT for determinism
327 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt |
328 LC_ALL=C sort >&2
329
330 ## STDOUT:
331 status=0
332 ## END
333 ## STDERR:
334 . 12345 builtin echo 1
335 . 12345 builtin echo 2
336 . 12345 exec grep ZZZ
337 . 12345 exec sort
338 ; process 12345: status 0
339 ; process 12345: status 0
340 ; process 12345: status 1
341 < 12345 proc myfunc
342 > 12345 proc myfunc
343 . builtin ':' begin
344 . builtin echo 'status=0'
345 . builtin set '+x'
346 < wait
347 > wait
348 [%1] PGID 12345 Done
349 | part 12345
350 | part 12345
351 | part 12345
352 ## END
353
354 #### Background process with fork and & (nondeterministic)
355 shopt --set oil:upgrade
356 set -x
357
358 {
359 sleep 0.1 &
360 wait
361
362 shopt -s oil:upgrade
363
364 fork {
365 sleep 0.1
366 }
367 wait
368 set +x
369 } 2>err.txt
370
371 # SORT for determinism
372 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt |
373 LC_ALL=C sort >&2
374
375 ## stdout-json: ""
376 ## STDERR:
377 . 12345 exec sleep 0.1
378 . 12345 exec sleep 0.1
379 ; process 12345: status 0
380 ; process 12345: status 0
381 . builtin fork
382 . builtin set '+x'
383 . builtin shopt -s 'oil:upgrade'
384 < wait
385 < wait
386 > wait
387 > wait
388 [%1] PID 12345 Done
389 [%1] PID 12345 Done
390 | fork 12345
391 | fork 12345
392 ## END
393
394 # others: redirects?
395
396 #### Here doc
397 shopt --set ysh:upgrade
398 shopt --unset errexit
399 set -x
400
401 {
402 : begin
403 tac <<EOF
404 3
405 2
406 EOF
407
408 set +x
409 } 2>err.txt
410
411 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
412
413 ## STDOUT:
414 2
415 3
416 ## END
417 ## STDERR:
418 . builtin ':' begin
419 | command 12345: tac
420 ; process 12345: status 0
421 . builtin set '+x'
422 ## END
423
424 #### Two here docs
425
426 # BUG: This trace shows an extra process?
427
428 shopt --set ysh:upgrade
429 shopt --unset errexit
430 set -x
431
432 {
433 cat - /dev/fd/3 <<EOF 3<<EOF2
434 xx
435 yy
436 EOF
437 zz
438 EOF2
439
440 set +x
441 } 2>err.txt
442
443 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
444
445 ## STDOUT:
446 xx
447 yy
448 zz
449 ## END
450 ## STDERR:
451 | command 12345: cat - /dev/fd/3
452 ; process 12345: status 0
453 . builtin set '+x'
454 ## END
455
456 #### Here doc greater than 4096 bytes
457
458 {
459 echo 'wc -l <<EOF'
460 seq 2000
461 echo 'EOF'
462 } > big-here.sh
463
464 wc -l big-here.sh
465
466 $SH -o ysh:upgrade -x big-here.sh 2>err.txt
467
468 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
469
470 ## STDOUT:
471 2002 big-here.sh
472 2000
473 ## END
474 ## STDERR:
475 | here doc 12345
476 | command 12345: wc -l
477 ; process 12345: status 0
478 ; process 12345: status 0
479 ## END
480
481 #### Control Flow
482 shopt --set oil:upgrade
483 set -x
484
485 for i in 1 2 3 {
486 echo $i
487 if (i === '2') {
488 break
489 }
490 }
491
492 for j in a b {
493 for k in y z {
494 echo $j $k
495 if (k === 'y') {
496 continue
497 }
498 }
499 }
500
501 proc zero {
502 return 0
503 }
504
505 proc one {
506 return 1
507 }
508
509 zero
510 # one
511
512 ## STDOUT:
513 1
514 2
515 a y
516 a z
517 b y
518 b z
519 ## END
520 ## STDERR:
521 . builtin echo 1
522 . builtin echo 2
523 + break 1
524 . builtin echo a y
525 + continue 1
526 . builtin echo a z
527 . builtin echo b y
528 + continue 1
529 . builtin echo b z
530 > proc zero
531 + return 0
532 < proc zero
533 ## END
534
535 #### Encoded argv uses shell encoding, not J8
536
537 shopt --set ysh:upgrade
538 set -x
539
540 echo $'one two\n' $'\u03bc'
541 ## STDOUT:
542 one two
543 μ
544 ## END
545 ## STDERR:
546 . builtin echo $'one two\n' 'μ'
547 ## END