1# Tests corresponding to the `Redirection' texinfo node.
2
3%prep
4  mkdir redir.tmp && cd redir.tmp
5
6  myfd=99
7  (echo >&$myfd) 2>msg
8  bad_fd_msg="${$(<msg)##*:}"
9
10%test
11
12  print 'This is file redir' >redir  &&  cat redir
130:'>' and '<' redirection
14>This is file redir
15
16  rm -f redir
17  print 'This is still file redir' <>redir >&0  &&  cat <>redir
180:'<>' redirection
19>This is still file redir
20
21  rm -f redir
22  print 'With a bar' >|redir  &&  cat redir
230:'>|' redirection
24>With a bar
25
26  rm -f redir
27  print 'With a bang' >!redir  &&  cat redir
280:'>!' redirection
29>With a bang
30
31  rm -f redir
32  print 'Line 1' >>redir  &&  print 'Line 2' >>redir  &&  cat redir
330:'>>' redirection
34>Line 1
35>Line 2
36
37  rm -f redir
38  print 'Line a' >>|redir  &&  print 'Line b' >>!redir
390:'>>|' and '>>!' redirection
40
41  foo=bar
42  cat <<'  HERE'
43  $foo
44  HERE
45  eval "$(print 'cat <<HERE\n$foo\nHERE')"
460:Here-documents
47>  $foo
48>bar
49
50  cat <<-HERE
51# note tabs at the start of the following lines
52	$foo$foo
53	HERE
540:Here-documents stripping tabs
55>barbar
56
57  cat <<-$'$HERE '`$(THERE) `'$((AND)) '"\EVERYWHERE"
58# tabs again.  sorry about the max miller.
59	Here's a funny thing.  Here is a funny thing.
60	I went home last night.  There's a funny thing.
61	Man walks into a $foo.  Ouch, it's an iron $foo.
62	$HERE `$(THERE) `$((AND)) \EVERYWHERE
630:Here-documents don't perform shell expansion on the initial word
64>Here's a funny thing.  Here is a funny thing.
65>I went home last night.  There's a funny thing.
66>Man walks into a $foo.  Ouch, it's an iron $foo.
67
68  cat <<-$'\x45\x4e\x44\t\x44\x4f\x43'
69# tabs again
70	This message is unfathomable.
71	END	DOC
720:Here-documents do perform $'...' expansion on the initial word
73>This message is unfathomable.
74
75  cat <<<"This is a line with a $foo in it"
760:'<<<' redirection
77>This is a line with a bar in it
78
79  cat <<<$'a\nb\nc'
800:here-strings with $'...' quoting
81>a
82>b
83>c
84
85# The following tests check that output of parsed here-documents works.
86# This isn't completely trivial because we convert the here-documents
87# internally to here-strings.  So we check again that we can output
88# the reevaluated here-strings correctly.  Hence there are three slightly
89# different stages.  We don't care how the output actually looks, so
90# we don't test that.
91  heretest() {
92    print First line
93    cat <<-HERE
94	$foo$foo met celeste  'but with extra'  "stuff to test quoting"
95	HERE
96    print Last line
97  }
98  heretest
99  eval "$(functions heretest)"
100  heretest
101  eval "$(functions heretest)"
102  heretest
1030:Re-evaluation of function output with here document, unquoted
104>First line
105>barbar met celeste  'but with extra'  "stuff to test quoting"
106>Last line
107>First line
108>barbar met celeste  'but with extra'  "stuff to test quoting"
109>Last line
110>First line
111>barbar met celeste  'but with extra'  "stuff to test quoting"
112>Last line
113
114  heretest() {
115    print First line
116    cat <<'    HERE'
117    $foo$foo met celeste  'but with extra'  "stuff to test quoting"
118    HERE
119    print Last line
120  }
121  heretest
122  eval "$(functions heretest)"
123  heretest
124  eval "$(functions heretest)"
125  heretest
1260:Re-evaluation of function output with here document, quoted
127>First line
128>    $foo$foo met celeste  'but with extra'  "stuff to test quoting"
129>Last line
130>First line
131>    $foo$foo met celeste  'but with extra'  "stuff to test quoting"
132>Last line
133>First line
134>    $foo$foo met celeste  'but with extra'  "stuff to test quoting"
135>Last line
136
137  read -r line <<'  HERE'
138  HERE
1391:No input, not even newline, from empty here document.
140
141  #
142  # exec tests: perform these in subshells so if they fail the
143  # shell won't exit.
144  #
145  (exec 3>redir  &&  print hello >&3  &&  print goodbye >&3  && cat redir)
1460:'>&' redirection
147>hello
148>goodbye
149
150  (exec 3<redir && read foo <&3 && print $foo && read foo <&3 && print $foo)
1510:'<&' redirection
152>hello
153>goodbye
154
155  ({ exec 3<&- } 2>/dev/null
156  exec 3<&-
157  read foo <&-)
1581:'<&-' redirection
159*?\(eval\):*: failed to close file descriptor 3:*
160
161  print foo >&-
1620:'>&-' redirection
163
164  (exec >&-
165  print foo)
1660:'>&-' with attempt to use closed fd
167*?\(eval\):2: write error:*
168
169  fn() { local foo; read foo; print $foo; }
170  coproc fn
171  print test output >&p
172  read bar <&p
173  print $bar
1740:'>&p' and '<&p' redirection
175>test output
176
177  ( print Output; print Error >& 2 ) >&errout  &&  cat errout
1780:'>&FILE' handling
179>Output
180>Error
181
182  rm -f errout
183  ( print Output2; print Error2 >& 2 ) &>errout  &&  cat errout
1840:'&>FILE' handling
185>Output2
186>Error2
187
188  rm -f errout
189  ( print Output3; print Error3 >& 2 ) >&|errout  &&  cat errout
190  ( print Output4; print Error4 >& 2 ) >&!errout  &&  cat errout
191  ( print Output5; print Error5 >& 2 ) &>|errout  &&  cat errout
192  ( print Output6; print Error6 >& 2 ) &>!errout  &&
193  ( print Output7; print Error7 >& 2 ) >>&errout  &&
194  ( print Output8; print Error8 >& 2 ) &>>errout  &&
195  ( print Output9; print Error9 >& 2 ) >>&|errout  &&
196  ( print Output10; print Error10 >& 2 ) &>>|errout  &&
197  ( print Output11; print Error11 >& 2 ) >>&!errout  &&
198  ( print Output12; print Error12 >& 2 ) &>>!errout  &&  cat errout
1990:'>&|', '>&!', '&>|', '&>!' redirection
200>Output3
201>Error3
202>Output4
203>Error4
204>Output5
205>Error5
206>Output6
207>Error6
208>Output7
209>Error7
210>Output8
211>Error8
212>Output9
213>Error9
214>Output10
215>Error10
216>Output11
217>Error11
218>Output12
219>Error12
220
221  rm -f errout
222  ( print Output; print Error 1>&2 ) 1>errout 2>&1  && cat errout
2230:'Combining > with >& (1)'
224>Output
225>Error
226
227  rm -f errout
228  ( print Output; print Error 1>&2 ) 2>&1 1>errout   &&  print errout:  &&
229  cat errout
2300:'Combining > with >& (2)'
231>Error
232>errout:
233>Output
234
235  rm -f errout
236  print doo be doo be doo >foo >bar 
237  print "foo: $(<foo)\nbar: $(<bar)"
2380:2-file multio
239>foo: doo be doo be doo
240>bar: doo be doo be doo
241
242  rm -f foo bar
243  print dont be dont be dont >foo | sed 's/dont/wont/g' >bar
2440:setup file+pipe multio
245
246  print "foo: $(<foo)\nbar: $(<bar)"
2470:read file+pipe multio
248>foo: dont be dont be dont
249>bar: wont be wont be wont
250
251  rm -f *
252  touch out1 out2
253  print All files >*
254  print *
255  print "out1: $(<out1)\nout2: $(<out2)"
2560:multio with globbing
257>out1 out2
258>out1: All files
259>out2: All files
260
261  print This is out1 >out1
262  print This is out2 >out2
2630:setup multio for input
264
265# Currently, <out{1,2} doesn't work: this is a bug.
266  cat <out*
2670:read multio input
268>This is out1
269>This is out2
270
271  cat out1 | sed s/out/bout/ <out2
2720:read multio input with pipe
273>This is bout1
274>This is bout2
275
276  unset NULLCMD
277  >out1
2781:null redir with NULLCMD unset
279?(eval):2: redirection with no command
280
281  echo this should still work >out1
282  print "$(<out1)"
2830:null redir in $(...) with NULLCMD unset
284>this should still work
285
286  READNULLCMD=cat
287  print cat input >out1
288  <out1
2891:READNULLCMD with NULLCMD unset
290?(eval):3: redirection with no command
291
292  NULLCMD=:
293  >out1
294  [[ ! -s out1 ]] || print out1 is not empty
2950:null redir with NULLCMD=:
296<input
297
298  print cat input >out1
299  <out1
3000:READNULLCMD
301>cat input
302
303  NULLCMD=cat
304  >out1
305  cat out1
3060:null redir with NULLCMD=cat
307<input
308>input
309
310  (myfd=
311  exec {myfd}>logfile
312  if [[ -z $myfd ]]; then
313    print "Ooops, failed to set myfd to a file descriptor." >&2
314  else
315    print This is my logfile. >&$myfd
316    print Examining contents of logfile...
317    cat logfile
318  fi)
3190:Using {fdvar}> syntax to open a new file descriptor
320>Examining contents of logfile...
321>This is my logfile.
322
323  (setopt noclobber
324   exec {myfd}>logfile2
325   echo $myfd
326   exec {myfd}>logfile3) | read myfd
327  (( ! ${pipestatus[1]} ))
3281q:NO_CLOBBER prevents overwriting parameter with allocated fd
329?(eval):4: can't clobber parameter myfd containing file descriptor $myfd
330
331  (setopt noclobber
332   exec {myfd}>logfile2b
333   print First open >&$myfd
334   rm -f logfile2b # prevent normal file no_clobberation
335   myotherfd="${myfd}+0"
336   exec {myotherfd}>logfile2b
337   print Overwritten >&$myotherfd)
338   cat logfile2b
3390:NO_CLOBBER doesn't complain about any other expression
340>Overwritten
341
342  (exec {myfd}>logfile4
343  echo $myfd
344  exec {myfd}>&-
345  print This message should disappear >&$myfd) | read myfd
346  (( ! ${pipestatus[1]} ))
3471q:Closing file descriptor using brace syntax
348?(eval):4: $myfd:$bad_fd_msg
349
350  typeset -r myfd
351  echo This should not appear {myfd}>nologfile
3521:Error opening file descriptor using readonly variable
353?(eval):2: can't allocate file descriptor to readonly parameter myfd
354
355  (typeset +r myfd
356  exec {myfd}>newlogfile
357  typeset -r myfd
358  exec {myfd}>&-)
3591:Error closing file descriptor using readonly variable
360?(eval):4: can't close file descriptor from readonly parameter myfd
361
362# This tests the here-string to filename optimisation; we can't
363# test that it's actually being optimised, but we can test that it
364# still works.
365  cat =(<<<$'This string has been replaced\nby a file containing it.\n')
3660:Optimised here-string to filename
367>This string has been replaced
368>by a file containing it.
369
370  print This f$'\x69'le contains d$'\x61'ta. >redirfile
371  print redirection:
372  cat<redirfile>outfile
373  print output:
374  cat outfile
375  print append:
376  cat>>outfile<redirfile
377  print more output:
378  cat outfile
3790:Parsing of redirection operators (no space required before operators)
380>redirection:
381>output:
382>This file contains data.
383>append:
384>more output:
385>This file contains data.
386>This file contains data.
387
388  $ZTST_testdir/../Src/zsh -fc 'exec >/nonexistent/nonexistent
389  echo output'
3900:failed exec redir, no POSIX_BUILTINS
391>output
392?zsh:1: no such file or directory: /nonexistent/nonexistent
393
394  $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
395  exec >/nonexistent/nonexistent
396  echo output'
3971:failed exec redir, POSIX_BUILTINS
398?zsh:2: no such file or directory: /nonexistent/nonexistent
399
400  $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
401  set >/nonexistent/nonexistent
402  echo output'
4031:failed special builtin redir, POSIX_BUILTINS
404?zsh:2: no such file or directory: /nonexistent/nonexistent
405
406  $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
407  command set >/nonexistent/nonexistent
408  echo output'
4090:failed special builtin redir with command prefix, POSIX_BUILTINS
410>output
411?zsh:2: no such file or directory: /nonexistent/nonexistent
412
413  $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
414  echo >/nonexistent/nonexistent
415  echo output'
4160:failed unspecial builtin redir, POSIX_BUILTINS
417>output
418?zsh:2: no such file or directory: /nonexistent/nonexistent
419
420  $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
421  . /nonexistent/nonexistent
422  echo output'
4231:failed dot, POSIX_BUILTINS
424?zsh:.:2: no such file or directory: /nonexistent/nonexistent
425
426  $ZTST_testdir/../Src/zsh -f -c '
427  . /nonexistent/nonexistent
428  echo output'
4290:failed dot, NO_POSIX_BUILTINS
430>output
431?zsh:.:2: no such file or directory: /nonexistent/nonexistent
432
433  $ZTST_testdir/../Src/zsh -f -o CONTINUE_ON_ERROR <<<'
434  readonly foo
435  foo=bar set output
436  echo output'
4370:failed assignment on posix special, CONTINUE_ON_ERROR
438>output
439?zsh: read-only variable: foo
440
441  $ZTST_testdir/../Src/zsh -f <<<'
442  readonly foo
443  foo=bar set output
444  echo output'
4451:failed assignment on posix special, NO_CONTINUE_ON_ERROR
446?zsh: read-only variable: foo
447
448  $ZTST_testdir/../Src/zsh -f -o CONTINUE_ON_ERROR <<<'
449  readonly foo
450  foo=bar echo output
451  echo output'
4520:failed assignment on non-posix-special, CONTINUE_ON_ERROR
453>output
454?zsh: read-only variable: foo
455
456  [</dev/null ]
4571:check behaviour with square brackets
458