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