1 #!/usr/bin/env bash
2 #
3 # xtrace test. Test PS4 and line numbers, etc.
4
5 #### set -o verbose prints unevaluated code
6 set -o verbose
7 x=foo
8 y=bar
9 echo $x
10 echo $(echo $y)
11 ## STDOUT:
12 foo
13 bar
14 ## STDERR:
15 x=foo
16 y=bar
17 echo $x
18 echo $(echo $y)
19 ## OK bash STDERR:
20 x=foo
21 y=bar
22 echo $x
23 echo $(echo $y)
24 ## END
25
26 #### xtrace with whitespace and quotes
27 set -o xtrace
28 echo '1 2' \' \"
29 ## STDOUT:
30 1 2 ' "
31 ## STDERR:
32 + echo '1 2' \' '"'
33 ## BUG dash STDERR:
34 + echo 1 2 ' "
35 ## END
36
37 #### CASE: xtrace with newlines
38 # bash and dash trace this badly. They print literal newlines, which I don't
39 # want.
40 set -x
41 echo $'[\n]'
42 ## STDOUT:
43 [
44 ]
45 ## stderr-json: "+ echo $'[\\n]'\n"
46 ## OK bash stderr-json: "+ echo '[\n]'\n"
47 ## N-I dash stdout-json: "$[\n]\n"
48 ## N-I dash stderr-json: "+ echo $[\\n]\n"
49
50 #### xtrace written before command executes
51 set -x
52 echo one >&2
53 echo two >&2
54 ## stdout-json: ""
55 ## STDERR:
56 + echo one
57 one
58 + echo two
59 two
60 ## OK mksh STDERR:
61 # mksh traces redirects!
62 + >&2
63 + echo one
64 one
65 + >&2
66 + echo two
67 two
68 ## END
69
70 #### PS4 is scoped
71 set -x
72 echo one
73 f() {
74 local PS4='- '
75 echo func;
76 }
77 f
78 echo two
79 ## STDERR:
80 + echo one
81 + f
82 + local 'PS4=- '
83 - echo func
84 + echo two
85 ## OK dash STDERR:
86 # dash loses information about spaces! There is a trailing space, but you
87 # can't see it.
88 + echo one
89 + f
90 + local PS4=-
91 - echo func
92 + echo two
93 ## OK mksh STDERR:
94 # local gets turned into typeset
95 + echo one
96 + f
97 + typeset 'PS4=- '
98 - echo func
99 + echo two
100 ## BUG osh STDERR:
101 # local gets turned into typeset
102 + echo one
103 + f
104 - echo func
105 + echo two
106 ## END
107
108 #### xtrace with variables in PS4
109 PS4='+$x:'
110 set -o xtrace
111 x=1
112 echo one
113 x=2
114 echo two
115 ## STDOUT:
116 one
117 two
118 ## STDERR:
119 +:x=1
120 +1:echo one
121 +1:x=2
122 +2:echo two
123 ## OK mksh STDERR:
124 # mksh has trailing spaces
125 +:x=1
126 +1:echo one
127 +1:x=2
128 +2:echo two
129 ## OK dash STDERR:
130 # dash evaluates it earlier
131 +1:x=1
132 +1:echo one
133 +2:x=2
134 +2:echo two
135 ## OK osh STDERR:
136 # dash evaluates it earlier
137 +1:echo one
138 +2:echo two
139 ## END
140
141 #### PS4 with unterminated ${
142 # osh shows inline error; maybe fail like dash/mksh?
143 x=1
144 PS4='+${x'
145 set -o xtrace
146 echo one
147 echo status=$?
148 ## STDOUT:
149 one
150 status=0
151 ## END
152 # mksh and dash both fail. bash prints errors to stderr.
153 ## OK dash stdout-json: ""
154 ## OK dash status: 2
155 ## OK mksh stdout-json: ""
156 ## OK mksh status: 1
157
158 #### PS4 with unterminated $(
159 # osh shows inline error; maybe fail like dash/mksh?
160 x=1
161 PS4='+$(x'
162 set -o xtrace
163 echo one
164 echo status=$?
165 ## STDOUT:
166 one
167 status=0
168 ## END
169 # mksh and dash both fail. bash prints errors to stderr.
170 ## OK dash stdout-json: ""
171 ## OK dash status: 2
172 ## OK mksh stdout-json: ""
173 ## OK mksh status: 1
174
175 #### PS4 with runtime error
176 # osh shows inline error; maybe fail like dash/mksh?
177 x=1
178 PS4='+oops $(( 1 / 0 )) \$'
179 set -o xtrace
180 echo one
181 echo status=$?
182 ## STDOUT:
183 one
184 status=0
185 ## END
186 # mksh and dash both fail. bash prints errors to stderr.
187 ## OK dash stdout-json: ""
188 ## OK dash status: 2
189 ## OK mksh stdout-json: ""
190 ## OK mksh status: 1
191