1 ## compare_shells: bash mksh zsh ash
2
3 #### File redirects with glob args (bash and zsh only)
4
5 touch one-bar
6
7 echo hi > one-*
8
9 cat one-bar
10
11 echo escaped > one-\*
12
13 cat one-\*
14
15 ## STDOUT:
16 hi
17 escaped
18 ## END
19 ## N-I dash/mksh/ash STDOUT:
20 escaped
21 ## END
22
23 #### File redirect without matching any file
24
25 echo hi > zz-*-xx
26 echo status=$?
27
28 echo zz*
29
30 ## STDOUT:
31 status=0
32 zz-*-xx
33 ## END
34
35 ## OK zsh status: 1
36 ## OK zsh STDOUT:
37 ## END
38
39 #### ysh behavior when glob doesn't match
40
41 shopt -s ysh:upgrade
42
43 echo hi > qq-*-zz
44 echo status=$?
45
46 echo qq*
47
48 ## status: 1
49 ## STDOUT:
50 ## END
51
52 ## N-I bash/mksh/ash status: 0
53 ## N-I bash/mksh/ash STDOUT:
54 status=0
55 qq-*-zz
56 ## END
57
58 #### File redirect without matching any file, with failglob
59
60 shopt -s failglob
61
62 echo hi > zz-*-xx
63 echo status=$?
64
65 echo zz*
66 echo status=$?
67
68 ## STDOUT:
69 status=1
70 status=1
71 ## END
72 ## N-I mksh/ash STDOUT:
73 status=0
74 zz-*-xx
75 status=0
76 ## END
77
78 ## OK zsh status: 1
79 ## OK zsh STDOUT:
80 ## END
81
82 #### Redirect to $empty (in function body)
83 empty=''
84 fun() { echo hi; } > $empty
85 fun
86 echo status=$?
87 ## STDOUT:
88 status=1
89 ## END
90 ## OK dash STDOUT:
91 status=2
92 ## END
93
94 #### Redirect to ''
95 echo hi > ''
96 echo status=$?
97 ## STDOUT:
98 status=1
99 ## END
100
101
102
103 #### File redirect to $var with glob char
104
105 touch two-bar
106
107 star='*'
108
109 # This gets glob-expanded, as it does outside redirects
110 echo hi > two-$star
111 echo status=$?
112
113 head two-bar two-\*
114
115 ## status: 1
116 ## STDOUT:
117 status=0
118 ==> two-bar <==
119 hi
120 ## END
121
122 ## OK mksh/zsh/ash status: 0
123 ## OK mksh/zsh/ash STDOUT:
124 status=0
125 ==> two-bar <==
126
127 ==> two-* <==
128 hi
129 ## END
130
131
132 #### File redirect that globs to more than one file (bash and zsh only)
133
134 touch foo-bar
135 touch foo-spam
136
137 echo hi > foo-*
138 echo status=$?
139
140 head foo-bar foo-spam
141
142 ## STDOUT:
143 status=1
144 ==> foo-bar <==
145
146 ==> foo-spam <==
147 ## END
148
149 ## N-I dash/mksh/ash STDOUT:
150 status=0
151 ==> foo-bar <==
152
153 ==> foo-spam <==
154 ## END
155
156 ## BUG zsh STDOUT:
157 status=0
158 ==> foo-bar <==
159 hi
160
161 ==> foo-spam <==
162 hi
163 ## END
164
165 #### File redirect with extended glob
166
167 shopt -s extglob
168
169 touch foo-bar
170
171 echo hi > @(*-bar|other)
172 echo status=$?
173
174 cat foo-bar
175
176 ## status: 0
177 ## STDOUT:
178 status=0
179 hi
180 ## END
181
182 ## N-I zsh status: 1
183 ## N-I dash/ash status: 2
184
185 ## N-I dash/zsh/ash STDOUT:
186 ## END
187
188 ## BUG mksh status: 0
189 ## BUG mksh STDOUT:
190 status=0
191 ## END
192
193 #### Extended glob that doesn't match anything
194 shopt -s extglob
195 rm bad_*
196
197 # They actually write this literal file! This is what EvalWordToString() does,
198 # as opposed to _EvalWordToParts.
199 echo foo > bad_@(*.cc|*.h)
200 echo status=$?
201
202 echo bad_*
203
204 shopt -s failglob
205
206 # Note: ysh:ugprade doesn't allow extended globs
207 # shopt -s ysh:upgrade
208
209 echo foo > bad_@(*.cc|*.h)
210 echo status=$?
211
212 ## STDOUT:
213 status=0
214 bad_@(*.cc|*.h)
215 status=1
216 ## END
217 ## N-I mksh STDOUT:
218 status=0
219 bad_@(*.cc|*.h)
220 status=0
221 ## END
222
223 ## N-I ash status: 2
224 ## N-I ash stdout-json: ""
225
226 ## N-I zsh status: 1
227 ## N-I zsh stdout-json: ""
228
229
230 #### Non-file redirects don't respect glob args (we differe from bash)
231
232 touch 10
233
234 exec 10>&1 # open stdout as descriptor 10
235
236 # Does this go to stdout? ONLY bash respects it, not zsh
237 echo should-not-be-on-stdout >& 1*
238
239 echo stdout
240 echo stderr >&2
241
242 ## status: 0
243
244 ## STDOUT:
245 stdout
246 ## END
247
248 ## BUG bash STDOUT:
249 should-not-be-on-stdout
250 stdout
251 ## END
252
253 ## N-I dash/zsh status: 127
254 ## N-I dash/zsh STDOUT:
255 ## END
256
257
258 #### Redirect with brace expansion isn't allowed
259
260 echo hi > a-{one,two}
261 echo status=$?
262
263 head a-*
264 echo status=$?
265
266
267 ## STDOUT:
268 status=1
269 status=1
270 ## END
271
272 ## N-I mksh/ash STDOUT:
273 status=0
274 hi
275 status=0
276 ## END
277
278 ## BUG zsh STDOUT:
279 status=0
280 ==> a-one <==
281 hi
282
283 ==> a-two <==
284 hi
285 status=0
286 ## END
287
288
289 #### File redirects have word splitting too!
290
291 file='foo bar'
292
293 echo hi > $file
294 echo status=$?
295
296 cat "$file"
297 echo status=$?
298
299 ## STDOUT:
300 status=1
301 status=1
302 ## END
303
304 ## OK mksh/zsh/ash STDOUT:
305 status=0
306 hi
307 status=0
308 ## END