1 # Oil xtrace
2
3 #### Customize PS4
4 shopt -s oil:basic
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:basic
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:basic 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 oil:basic
60 set -x
61
62 shfunc() {
63 : $1
64 }
65
66 proc p {
67 : $1
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:basic
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 source-argv: "$@"' > lib.sh
100
101 shopt --set oil:basic
102 set -x
103
104 source lib.sh 1 2 3
105
106 ## STDOUT:
107 source-argv: 1 2 3
108 ## END
109 ## STDERR:
110 > source lib.sh 1 2 3
111 . builtin echo 'source-argv:' 1 2 3
112 < source lib.sh
113 ## END
114
115 #### external and builtin
116 shopt --set oil:basic
117 shopt --unset errexit
118 set -x
119
120 {
121 env false
122 true
123 set +x
124 } 2>err.txt
125
126 # normalize PIDs, assumed to be 2 or more digits
127 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
128
129 ## stdout-json: ""
130 ## STDERR:
131 | command 12345: env false
132 ; process 12345: status 1
133 . builtin true
134 . builtin set '+x'
135 ## END
136
137 #### subshell
138 shopt --set oil:basic
139 shopt --unset errexit
140 set -x
141
142 proc p {
143 : p
144 }
145
146 {
147 : begin
148 (
149 : 1
150 p
151 exit 3
152 )
153 set +x
154 } 2>err.txt
155
156 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
157
158 ## stdout-json: ""
159 ## STDERR:
160 . builtin ':' begin
161 | forkwait 12345
162 . 12345 builtin ':' 1
163 > 12345 proc p
164 . 12345 builtin ':' p
165 < 12345 proc p
166 + 12345 exit 3
167 ; process 12345: status 3
168 . builtin set '+x'
169 ## END
170
171 #### command sub
172 shopt --set oil:basic
173 set -x
174
175 {
176 echo foo=$(echo bar)
177 set +x
178
179 } 2>err.txt
180
181 # HACK: sort because xtrace output has non-determinism.
182 # This is arguably a bug -- see issue #995.
183 # The real fix might be to sys.stderr.flush() in few places?
184 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt | LANG=C sort >&2
185
186 ## STDOUT:
187 foo=bar
188 ## END
189 ## STDERR:
190 . 12345 builtin echo bar
191 . builtin echo 'foo=bar'
192 . builtin set '+x'
193 ; process 12345: status 0
194 | command sub 12345
195 ## END
196
197 #### process sub (nondeterministic)
198 shopt --set oil:basic
199 shopt --unset errexit
200 set -x
201
202 # we wait() for them all at the end
203
204 {
205 : begin
206 cat <(seq 2) <(echo 1)
207 set +x
208 } 2>err.txt
209
210 # SORT for determinism
211 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g; s|/fd/.|/fd/N|g' err.txt |
212 LC_ALL=C sort >&2
213 #cat err.txt >&2
214
215 ## STDOUT:
216 1
217 2
218 1
219 ## END
220
221 ## STDERR:
222 . 12345 builtin echo 1
223 . 12345 exec seq 2
224 . builtin ':' begin
225 . builtin set '+x'
226 ; process 12345: status 0
227 ; process 12345: status 0
228 ; process 12345: status 0
229 | command 12345: cat '/dev/fd/N' '/dev/fd/N'
230 | proc sub 12345
231 | proc sub 12345
232 ## END
233
234 #### pipeline (nondeterministic)
235 shopt --set oil:basic
236 set -x
237
238 myfunc() {
239 echo 1
240 echo 2
241 }
242
243 {
244 : begin
245 myfunc | sort | wc -l
246 set +x
247 } 2>err.txt
248
249 # SORT for determinism
250 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g; s|/fd/.|/fd/N|g' err.txt |
251 LC_ALL=C sort >&2
252
253 ## STDOUT:
254 2
255 ## END
256 ## STDERR:
257 . 12345 builtin echo 1
258 . 12345 builtin echo 2
259 . 12345 exec sort
260 < 12345 proc myfunc
261 > 12345 proc myfunc
262 ; process 12345: status 0
263 ; process 12345: status 0
264 ; process 12345: status 0
265 | command 12345: wc -l
266 | part 12345
267 | part 12345
268 . builtin ':' begin
269 . builtin set '+x'
270 < pipeline
271 > pipeline
272 ## END
273
274 #### singleton pipeline
275
276 # Hm extra tracing
277
278 shopt --set oil:basic
279 set -x
280
281 : begin
282 ! false
283 : end
284
285 ## stdout-json: ""
286 ## STDERR:
287 . builtin ':' begin
288 > pipeline
289 . builtin false
290 < pipeline
291 . builtin ':' end
292 ## END
293
294 #### Background pipeline (separate code path)
295
296 shopt --set oil:basic
297 shopt --unset errexit
298 set -x
299
300 myfunc() {
301 echo 2
302 echo 1
303 }
304
305 {
306 : begin
307 myfunc | sort | grep ZZZ &
308 wait
309 echo status=$?
310 set +x
311 } 2>err.txt
312
313 # SORT for determinism
314 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt |
315 LC_ALL=C sort >&2
316
317 ## STDOUT:
318 status=0
319 ## END
320 ## STDERR:
321 . 12345 builtin echo 1
322 . 12345 builtin echo 2
323 . 12345 exec grep ZZZ
324 . 12345 exec sort
325 ; process 12345: status 0
326 ; process 12345: status 0
327 ; process 12345: status 1
328 < 12345 proc myfunc
329 > 12345 proc myfunc
330 . builtin ':' begin
331 . builtin echo 'status=0'
332 . builtin set '+x'
333 < wait
334 > wait
335 | part 12345
336 | part 12345
337 | part 12345
338 ## END
339
340 #### Background process with fork and & (nondeterministic)
341 shopt --set oil:basic
342 set -x
343
344 {
345 sleep 0.1 &
346 wait
347
348 shopt -s oil:basic
349
350 fork {
351 sleep 0.1
352 }
353 wait
354 set +x
355 } 2>err.txt
356
357 # SORT for determinism
358 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt |
359 LC_ALL=C sort >&2
360
361 ## stdout-json: ""
362 ## STDERR:
363 . 12345 exec sleep 0.1
364 . 12345 exec sleep 0.1
365 ; process 12345: status 0
366 ; process 12345: status 0
367 . builtin fork
368 . builtin set '+x'
369 . builtin shopt -s 'oil:basic'
370 < wait
371 < wait
372 > wait
373 > wait
374 | fork 12345
375 | fork 12345
376 ## END
377
378 # others: redirects?
379
380 #### here doc
381 shopt --set oil:basic
382 shopt --unset errexit
383 set -x
384
385 {
386 : begin
387 tac <<EOF
388 3
389 2
390 EOF
391
392 set +x
393 } 2>err.txt
394
395 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
396
397 ## STDOUT:
398 2
399 3
400 ## END
401 ## STDERR:
402 . builtin ':' begin
403 | here doc 12345
404 | command 12345: tac
405 ; process 12345: status 0
406 ; process 12345: status 0
407 . builtin set '+x'
408 ## END
409
410 #### Two here docs
411
412 # BUG: This trace shows an extra process?
413
414 shopt --set oil:basic
415 shopt --unset errexit
416 set -x
417
418 {
419 cat - /dev/fd/3 <<EOF 3<<EOF2
420 xx
421 yy
422 EOF
423 zz
424 EOF2
425
426 set +x
427 } 2>err.txt
428
429 sed --regexp-extended 's/[[:digit:]]{2,}/12345/g' err.txt >&2
430
431 ## STDOUT:
432 xx
433 yy
434 zz
435 ## END
436 ## STDERR:
437 | here doc 12345
438 | here doc 12345
439 | command 12345: cat - '/dev/fd/3'
440 ; process 12345: status 0
441 ; process 12345: status 0
442 ; process 12345: status 0
443 . builtin set '+x'
444 ## END
445
446 #### Control Flow
447 shopt --set oil:basic
448 set -x
449
450 for i in 1 2 3 {
451 echo $i
452 if (i === '2') {
453 break
454 }
455 }
456 ## STDOUT:
457 1
458 2
459 ## END
460 ## STDERR:
461 . builtin echo 1
462 . builtin echo 2
463 + break
464 ## END
465
466 #### QSN encoded argv
467 shopt --set oil:basic
468 set -x
469
470 echo $'one two\n' $'\u03bc'
471 ## STDOUT:
472 one two
473 μ
474 ## END
475 ## STDERR:
476 . builtin echo 'one two\n' 'μ'
477 ## END