1 # xtrace test. Test PS4 and line numbers, etc.
2
3 ## oils_failures_allowed: 1
4 ## compare_shells: bash dash mksh
5
6 #### unset PS4
7 case $SH in dash) echo 'weird bug'; exit ;; esac
8
9 set -x
10 echo 1
11 unset PS4
12 echo 2
13 ## STDOUT:
14 1
15 2
16 ## STDERR:
17 + echo 1
18 + unset PS4
19 echo 2
20 ## END
21
22 ## BUG dash STDOUT:
23 weird bug
24 ## END
25 ## BUG dash STDERR:
26 ## END
27
28 #### set -o verbose prints unevaluated code
29 set -o verbose
30 x=foo
31 y=bar
32 echo $x
33 echo $(echo $y)
34 ## STDOUT:
35 foo
36 bar
37 ## STDERR:
38 x=foo
39 y=bar
40 echo $x
41 echo $(echo $y)
42 ## OK bash STDERR:
43 x=foo
44 y=bar
45 echo $x
46 echo $(echo $y)
47 ## END
48
49 #### xtrace with unprintable chars
50 case $SH in dash) exit ;; esac
51
52 $SH >stdout 2>stderr <<'EOF'
53
54 s=$'a\x03b\004c\x00d'
55 set -o xtrace
56 echo "$s"
57 EOF
58
59 show_hex() { od -A n -t c -t x1; }
60
61 echo STDOUT
62 cat stdout | show_hex
63 echo
64
65 echo STDERR
66 grep 'echo' stderr
67
68 ## STDOUT:
69 STDOUT
70 a 003 b 004 c \0 d \n
71 61 03 62 04 63 00 64 0a
72
73 STDERR
74 + echo $'a\u0003b\u0004c\u0000d'
75 ## END
76
77 ## OK bash STDOUT:
78 STDOUT
79 a 003 b 004 c \n
80 61 03 62 04 63 0a
81
82 STDERR
83 + echo $'a\003b\004c'
84 ## END
85
86 ## BUG mksh STDOUT:
87 STDOUT
88 a ; 004 c \r \n
89 61 3b 04 63 0d 0a
90
91 STDERR
92 + echo $'a;\004c\r'
93 ## END
94
95 ## N-I dash stdout-json: ""
96
97 #### xtrace with unicode chars
98 case $SH in dash) exit ;; esac
99
100 mu1='[μ]'
101 mu2=$'[\u03bc]'
102
103 set -o xtrace
104 echo "$mu1" "$mu2"
105
106 ## STDOUT:
107 [μ] [μ]
108 ## END
109 ## STDERR:
110 + echo '[μ]' '[μ]'
111 ## END
112 ## N-I dash stdout-json: ""
113 ## N-I dash stderr-json: ""
114
115 #### xtrace with paths
116 set -o xtrace
117 echo my-dir/my_file.cc
118 ## STDOUT:
119 my-dir/my_file.cc
120 ## END
121 ## STDERR:
122 + echo my-dir/my_file.cc
123 ## END
124
125 #### xtrace with tabs
126 case $SH in dash) exit ;; esac
127
128 set -o xtrace
129 echo $'[\t]'
130 ## stdout-json: "[\t]\n"
131 ## STDERR:
132 + echo $'[\t]'
133 ## END
134 # this is a bug because it's hard to see
135 ## BUG bash stderr-json: "+ echo '[\t]'\n"
136 ## N-I dash stdout-json: ""
137 ## N-I dash stderr-json: ""
138
139 #### xtrace with whitespace, quotes, and backslash
140 set -o xtrace
141 echo '1 2' \' \" \\
142 ## STDOUT:
143 1 2 ' " \
144 ## END
145
146 # YSH is different because backslashes require $'\\' and not '\', but that's OK
147 ## STDERR:
148 + echo '1 2' $'\'' '"' $'\\'
149 ## END
150
151 ## OK bash/mksh STDERR:
152 + echo '1 2' \' '"' '\'
153 ## END
154
155 ## BUG dash STDERR:
156 + echo 1 2 ' " \
157 ## END
158
159 #### xtrace with newlines
160 # bash and dash trace this badly. They print literal newlines, which I don't
161 # want.
162 set -x
163 echo $'[\n]'
164 ## STDOUT:
165 [
166 ]
167 ## STDERR:
168 + echo $'[\n]'
169 ## END
170 # bash has ugly output that spans lines
171 ## OK bash STDERR:
172 + echo '[
173 ]'
174 ## END
175 ## N-I dash STDOUT:
176 $[
177 ]
178 ## END
179 ## N-I dash STDERR:
180 + echo $[\n]
181 ## END
182
183 #### xtrace written before command executes
184 set -x
185 echo one >&2
186 echo two >&2
187 ## stdout-json: ""
188 ## STDERR:
189 + echo one
190 one
191 + echo two
192 two
193 ## OK mksh STDERR:
194 # mksh traces redirects!
195 + >&2
196 + echo one
197 one
198 + >&2
199 + echo two
200 two
201 ## END
202
203 #### Assignments and assign builtins
204 set -x
205 x=1 x=2; echo $x; readonly x=3
206 ## STDOUT:
207 2
208 ## END
209 ## STDERR:
210 + x=1
211 + x=2
212 + echo 2
213 + readonly x=3
214 ## END
215 ## OK dash STDERR:
216 + x=1 x=2
217 + echo 2
218 + readonly x=3
219 ## END
220 ## OK bash STDERR:
221 + x=1
222 + x=2
223 + echo 2
224 + readonly x=3
225 + x=3
226 ## END
227 ## OK mksh STDERR:
228 + x=1 x=2
229 + echo 2
230 + readonly 'x=3'
231 ## END
232
233 #### [[ ]]
234 case $SH in dash|mksh) exit ;; esac
235
236 set -x
237
238 dir=/
239 if [[ -d $dir ]]; then
240 (( a = 42 ))
241 fi
242 ## stdout-json: ""
243 ## STDERR:
244 + dir=/
245 + [[ -d $dir ]]
246 + (( a = 42 ))
247 ## END
248 ## OK bash STDERR:
249 + dir=/
250 + [[ -d / ]]
251 + (( a = 42 ))
252 ## END
253 ## N-I dash/mksh stderr-json: ""
254
255 #### PS4 is scoped
256 set -x
257 echo one
258 f() {
259 local PS4='- '
260 echo func;
261 }
262 f
263 echo two
264 ## STDERR:
265 + echo one
266 + f
267 + local 'PS4=- '
268 - echo func
269 + echo two
270 ## END
271 ## OK osh STDERR:
272 + echo one
273 + f
274 + local PS4='- '
275 - echo func
276 + echo two
277 ## END
278 ## OK dash STDERR:
279 # dash loses information about spaces! There is a trailing space, but you
280 # can't see it.
281 + echo one
282 + f
283 + local PS4=-
284 - echo func
285 + echo two
286 ## END
287 ## OK mksh STDERR:
288 # local gets turned into typeset
289 + echo one
290 + f
291 + typeset 'PS4=- '
292 - echo func
293 + echo two
294 ## END
295
296 #### xtrace with variables in PS4
297 PS4='+$x:'
298 set -o xtrace
299 x=1
300 echo one
301 x=2
302 echo two
303 ## STDOUT:
304 one
305 two
306 ## END
307
308 ## STDERR:
309 +:x=1
310 +1:echo one
311 +1:x=2
312 +2:echo two
313 ## END
314
315 ## OK mksh STDERR:
316 # mksh has trailing spaces
317 +:x=1
318 +1:echo one
319 +1:x=2
320 +2:echo two
321 ## END
322
323 ## OK osh/dash STDERR:
324 # the PS4 string is evaluated AFTER the variable is set. That's OK
325 +1:x=1
326 +1:echo one
327 +2:x=2
328 +2:echo two
329 ## END
330
331 #### PS4 with unterminated ${
332 # osh shows inline error; maybe fail like dash/mksh?
333 x=1
334 PS4='+${x'
335 set -o xtrace
336 echo one
337 echo status=$?
338 ## STDOUT:
339 one
340 status=0
341 ## END
342 # mksh and dash both fail. bash prints errors to stderr.
343 ## OK dash stdout-json: ""
344 ## OK dash status: 2
345 ## OK mksh stdout-json: ""
346 ## OK mksh status: 1
347
348 #### PS4 with unterminated $(
349 # osh shows inline error; maybe fail like dash/mksh?
350 x=1
351 PS4='+$(x'
352 set -o xtrace
353 echo one
354 echo status=$?
355 ## STDOUT:
356 one
357 status=0
358 ## END
359 # mksh and dash both fail. bash prints errors to stderr.
360 ## OK dash stdout-json: ""
361 ## OK dash status: 2
362 ## OK mksh stdout-json: ""
363 ## OK mksh status: 1
364
365 #### PS4 with runtime error
366 # osh shows inline error; maybe fail like dash/mksh?
367 x=1
368 PS4='+oops $(( 1 / 0 )) \$'
369 set -o xtrace
370 echo one
371 echo status=$?
372 ## STDOUT:
373 one
374 status=0
375 ## END
376 # mksh and dash both fail. bash prints errors to stderr.
377 ## OK dash stdout-json: ""
378 ## OK dash status: 2
379 ## OK mksh stdout-json: ""
380 ## OK mksh status: 1
381
382
383 #### Reading $? in PS4
384 PS4='[last=$?] '
385 set -x
386 false
387 echo ok
388 ## STDOUT:
389 ok
390 ## END
391 ## STDERR:
392 [last=0] false
393 [last=1] echo ok
394 ## END
395 ## OK osh STDERR:
396 [last=0] 'false'
397 [last=1] echo ok
398 ## END
399
400
401 #### Regression: xtrace for "declare -a a+=(v)"
402 case $SH in dash|mksh) exit ;; esac
403
404 a=(1)
405 set -x
406 declare a+=(2)
407 ## STDERR:
408 + declare a+=(2)
409 ## END
410 ## OK bash STDERR:
411 + a+=('2')
412 + declare a
413 ## END
414 ## N-I dash/mksh STDERR:
415 ## END
416
417
418 #### Regression: xtrace for "a+=(v)"
419 case $SH in dash|mksh) exit ;; esac
420
421 a=(1)
422 set -x
423 a+=(2)
424 ## STDERR:
425 + a+=(2)
426 ## END
427 ## N-I dash/mksh STDERR:
428 ## END