1 ## oils_failures_allowed: 0
2 ## compare_shells: bash dash mksh
3
4 # Notes:
5 # - ash is just like dash, so don't bother testing
6 # - zsh fails several cases
7
8 #### >$file touches a file
9 rm -f myfile
10 test -f myfile
11 echo status=$?
12
13 >myfile
14 test -f myfile
15 echo status=$?
16
17 ## STDOUT:
18 status=1
19 status=0
20 ## END
21
22 # regression for OSH
23 ## stderr-json: ""
24
25 #### $(< $file) yields the contents of the file
26
27 echo FOO > myfile
28 foo=$(< myfile)
29 echo $foo
30
31 ## STDOUT:
32 FOO
33 ## END
34
35 ## N-I dash/ash/yash STDOUT:
36
37 ## END
38
39 #### $(< file) with more statements
40
41 # note that it doesn't do this without a command sub!
42 # It's apparently a special case in bash, mksh, and zsh?
43 foo=$(echo begin; < myfile)
44 echo $foo
45 echo ---
46
47 foo=$(< myfile; echo end)
48 echo $foo
49 echo ---
50
51 foo=$(< myfile; <myfile)
52 echo $foo
53 echo ---
54
55 ## STDOUT:
56 begin
57 ---
58 end
59 ---
60
61 ---
62 ## END
63 # weird, zsh behaves differently
64 ## OK zsh STDOUT:
65 begin
66 FOO
67 ---
68 FOO
69 end
70 ---
71 FOO
72 FOO
73 ---
74 ## END
75
76
77 #### < file in pipeline and subshell doesn't work
78 echo FOO > file2
79
80 # This only happens in command subs, which is weird
81 < file2 | tr A-Z a-z
82 ( < file2 )
83 echo end
84 ## STDOUT:
85 end
86 ## END
87
88
89 #### Leading redirect in a simple command
90 echo hello >$TMP/hello.txt # temporary fix
91 <$TMP/hello.txt cat
92 ## stdout: hello
93
94 #### Redirect in the middle of a simple command
95 f=$TMP/out
96 echo -n 1 2 '3 ' > $f
97 echo -n 4 5 >> $f '6 '
98 echo -n 7 >> $f 8 '9 '
99 echo -n >> $f 1 2 '3 '
100 echo >> $f -n 4 5 '6'
101
102 cat $f
103 echo
104 ## STDOUT:
105 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6
106 ## END
107
108 #### Redirect in command sub
109 FOO=$(echo foo 1>&2)
110 echo $FOO
111 ## stdout:
112 ## stderr: foo
113
114 #### Redirect in the middle of two assignments
115 FOO=foo >$TMP/out.txt BAR=bar printenv.py FOO BAR
116 tac $TMP/out.txt
117 ## STDOUT:
118 bar
119 foo
120 ## END
121
122 #### Redirect in assignment
123 # dash captures stderr to a file here, which seems correct. Bash doesn't and
124 # just lets it go to actual stderr.
125 # For now we agree with dash/mksh, since it involves fewer special cases in the
126 # code.
127
128 FOO=$(echo foo 1>&2) 2>$TMP/no-command.txt
129 echo FILE=
130 cat $TMP/no-command.txt
131 echo "FOO=$FOO"
132 ## STDOUT:
133 FILE=
134 foo
135 FOO=
136 ## END
137 ## BUG bash STDOUT:
138 FILE=
139 FOO=
140 ## END
141
142
143 #### Redirect in function body
144 fun() { echo hi; } 1>&2
145 fun
146 ## STDOUT:
147 ## END
148 ## STDERR:
149 hi
150 ## END
151
152 #### Redirect in function body is evaluated multiple times
153 i=0
154 fun() { echo "file $i"; } 1> "$TMP/file$((i++))"
155 fun
156 fun
157 echo i=$i
158 echo __
159 cat $TMP/file0
160 echo __
161 cat $TMP/file1
162 ## STDOUT:
163 i=2
164 __
165 file 1
166 __
167 file 2
168 ## END
169 ## N-I dash stdout-json: ""
170 ## N-I dash status: 2
171
172 #### Redirect in function body AND function call
173 fun() { echo hi; } 1>&2
174 fun 2>&1
175 ## STDOUT:
176 hi
177 ## END
178 ## STDERR:
179 ## END
180
181 #### redirect bash extensions: [[ (( for ((
182
183 case $SH in dash|mksh) exit ;; esac
184
185 rm -f dbracket dparen for-expr
186
187 [[ x = x ]] > dbracket
188
189 (( 42 )) > dparen
190
191 for ((x = 0; x < 1; ++x)); do
192 echo for-expr
193 done > for-expr
194
195 wc -l dbracket dparen for-expr
196
197 ## STDOUT:
198 0 dbracket
199 0 dparen
200 1 for-expr
201 1 total
202 ## END
203
204 ## N-I dash/mksh STDOUT:
205 ## END
206
207 #### redirect if
208 if true; then
209 echo if-body
210 fi >out
211
212 cat out
213
214 ## STDOUT:
215 if-body
216 ## END
217
218 #### redirect case
219 case foo in
220 foo)
221 echo case-body
222 ;;
223 esac > out
224
225 cat out
226
227 ## STDOUT:
228 case-body
229 ## END
230
231 #### redirect while
232 while true; do
233 echo while-body
234 break
235 done > out
236
237 cat out
238
239 ## STDOUT:
240 while-body
241 ## END
242
243 #### redirect for loop
244 for i in $(seq 3)
245 do
246 echo $i
247 done > $TMP/redirect-for-loop.txt
248 cat $TMP/redirect-for-loop.txt
249 ## STDOUT:
250 1
251 2
252 3
253 ## END
254
255 #### redirect subshell
256 ( echo foo ) 1>&2
257 ## stderr: foo
258 ## stdout-json: ""
259
260 #### Prefix redirect for loop -- not allowed
261 >$TMP/redirect2.txt for i in $(seq 3)
262 do
263 echo $i
264 done
265 cat $TMP/redirect2.txt
266 ## status: 2
267 ## OK mksh status: 1
268
269 #### Brace group redirect
270 # Suffix works, but prefix does NOT work.
271 # That comes from '| compound_command redirect_list' in the grammar!
272 { echo block-redirect; } > $TMP/br.txt
273 cat $TMP/br.txt | wc -c
274 ## stdout: 15
275
276 #### Redirect function stdout
277 f() { echo one; echo two; }
278 f > $TMP/redirect-func.txt
279 cat $TMP/redirect-func.txt
280 ## STDOUT:
281 one
282 two
283 ## END
284
285 #### Nested function stdout redirect
286 # Shows that a stack is necessary.
287 inner() {
288 echo i1
289 echo i2
290 }
291 outer() {
292 echo o1
293 inner > $TMP/inner.txt
294 echo o2
295 }
296 outer > $TMP/outer.txt
297 cat $TMP/inner.txt
298 echo --
299 cat $TMP/outer.txt
300 ## STDOUT:
301 i1
302 i2
303 --
304 o1
305 o2
306 ## END