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