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\x03b\x04c\x00d'
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 tabs
76 case $SH in (dash) exit ;; esac
77
78 set -o xtrace
79 echo $'[\t]'
80 ## stdout-json: "[\t]\n"
81 ## STDERR:
82 + echo $'[\t]'
83 ## END
84 # this is a bug because it's hard to see
85 ## BUG bash stderr-json: "+ echo '[\t]'\n"
86 ## N-I dash stdout-json: ""
87 ## N-I dash stderr-json: ""
88
89 #### xtrace with whitespace, quotes, and backslash
90 set -o xtrace
91 echo '1 2' \' \" \\
92 ## STDOUT:
93 1 2 ' " \
94 ## END
95
96 # Oil is different bceause backslashes require $'\\' and not '\', but that's OK
97 ## STDERR:
98 + echo '1 2' $'\'' '"' $'\\'
99 ## END
100
101 ## OK bash/mksh STDERR:
102 + echo '1 2' \' '"' '\'
103 ## END
104
105 ## BUG dash STDERR:
106 + echo 1 2 ' " \
107 ## END
108
109 #### xtrace with newlines
110 # bash and dash trace this badly. They print literal newlines, which I don't
111 # want.
112 set -x
113 echo $'[\n]'
114 ## STDOUT:
115 [
116 ]
117 ## STDERR:
118 + echo $'[\n]'
119 ## END
120 # bash has ugly output that spans lines
121 ## OK bash STDERR:
122 + echo '[
123 ]'
124 ## END
125 ## N-I dash stdout-json: "$[\n]\n"
126 ## N-I dash stderr-json: "+ echo $[\\n]\n"
127
128 #### xtrace written before command executes
129 set -x
130 echo one >&2
131 echo two >&2
132 ## stdout-json: ""
133 ## STDERR:
134 + echo one
135 one
136 + echo two
137 two
138 ## OK mksh STDERR:
139 # mksh traces redirects!
140 + >&2
141 + echo one
142 one
143 + >&2
144 + echo two
145 two
146 ## END
147
148 #### Assignments and assign builtins
149 set -x
150 x=1 x=2; echo $x; readonly x=3
151 ## STDOUT:
152 2
153 ## END
154 ## STDERR:
155 + x=1
156 + x=2
157 + echo 2
158 + readonly x=3
159 ## END
160 ## OK dash STDERR:
161 + x=1 x=2
162 + echo 2
163 + readonly x=3
164 ## END
165 ## OK dash STDERR:
166 + x=1 x=2
167 + echo 2
168 + readonly x=3
169 ## END
170 ## OK bash STDERR:
171 + x=1
172 + x=2
173 + echo 2
174 + readonly x=3
175 + x=3
176 ## END
177 ## OK mksh STDERR:
178 + x=1 x=2
179 + echo 2
180 + readonly 'x=3'
181 ## END
182
183 #### [[ ]]
184 case $SH in (dash|mksh) exit ;; esac
185
186 set -x
187
188 dir=/
189 if [[ -d $dir ]]; then
190 (( a = 42 ))
191 fi
192 ## stdout-json: ""
193 ## STDERR:
194 + dir='/'
195 + [[ -d $dir ]]
196 + (( a = 42 ))
197 ## END
198 ## OK bash STDERR:
199 + dir=/
200 + [[ -d / ]]
201 + (( a = 42 ))
202 ## END
203 ## N-I dash/mksh stderr-json: ""
204
205 #### PS4 is scoped
206 set -x
207 echo one
208 f() {
209 local PS4='- '
210 echo func;
211 }
212 f
213 echo two
214 ## STDERR:
215 + echo one
216 + f
217 + local 'PS4=- '
218 - echo func
219 + echo two
220 ## END
221 ## OK osh STDERR:
222 + echo one
223 + f
224 + local PS4='- '
225 - echo func
226 + echo two
227 ## END
228 ## OK dash STDERR:
229 # dash loses information about spaces! There is a trailing space, but you
230 # can't see it.
231 + echo one
232 + f
233 + local PS4=-
234 - echo func
235 + echo two
236 ## END
237 ## OK mksh STDERR:
238 # local gets turned into typeset
239 + echo one
240 + f
241 + typeset 'PS4=- '
242 - echo func
243 + echo two
244 ## END
245
246 #### xtrace with variables in PS4
247 PS4='+$x:'
248 set -o xtrace
249 x=1
250 echo one
251 x=2
252 echo two
253 ## STDOUT:
254 one
255 two
256 ## END
257
258 ## STDERR:
259 +:x=1
260 +1:echo one
261 +1:x=2
262 +2:echo two
263 ## END
264
265 ## OK mksh STDERR:
266 # mksh has trailing spaces
267 +:x=1
268 +1:echo one
269 +1:x=2
270 +2:echo two
271 ## END
272
273 ## OK osh/dash STDERR:
274 # the PS4 string is evaluated AFTER the variable is set. That's OK
275 +1:x=1
276 +1:echo one
277 +2:x=2
278 +2:echo two
279 ## END
280
281 #### PS4 with unterminated ${
282 # osh shows inline error; maybe fail like dash/mksh?
283 x=1
284 PS4='+${x'
285 set -o xtrace
286 echo one
287 echo status=$?
288 ## STDOUT:
289 one
290 status=0
291 ## END
292 # mksh and dash both fail. bash prints errors to stderr.
293 ## OK dash stdout-json: ""
294 ## OK dash status: 2
295 ## OK mksh stdout-json: ""
296 ## OK mksh status: 1
297
298 #### PS4 with unterminated $(
299 # osh shows inline error; maybe fail like dash/mksh?
300 x=1
301 PS4='+$(x'
302 set -o xtrace
303 echo one
304 echo status=$?
305 ## STDOUT:
306 one
307 status=0
308 ## END
309 # mksh and dash both fail. bash prints errors to stderr.
310 ## OK dash stdout-json: ""
311 ## OK dash status: 2
312 ## OK mksh stdout-json: ""
313 ## OK mksh status: 1
314
315 #### PS4 with runtime error
316 # osh shows inline error; maybe fail like dash/mksh?
317 x=1
318 PS4='+oops $(( 1 / 0 )) \$'
319 set -o xtrace
320 echo one
321 echo status=$?
322 ## STDOUT:
323 one
324 status=0
325 ## END
326 # mksh and dash both fail. bash prints errors to stderr.
327 ## OK dash stdout-json: ""
328 ## OK dash status: 2
329 ## OK mksh stdout-json: ""
330 ## OK mksh status: 1
331
332
333 #### Reading $? in PS4
334 PS4='[last=$?] '
335 set -x
336 false
337 echo ok
338 ## STDOUT:
339 ok
340 ## END
341 ## STDERR:
342 [last=0] false
343 [last=1] echo ok
344 ## END