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
|