OILS / spec / redirect-command.test.sh View on Github | oils.pub

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