1 #!/bin/bash
2
3 ### Leading redirect
4 echo hello >tests/hello.txt # temporary fix
5 <tests/hello.txt cat
6 # stdout: hello
7
8 ### No command
9 # Hm this is valid in bash and dash. It's parsed as an assigment with a
10 # redirect, which doesn't make sense. But it's a mistake, and should be a W2
11 # warning for us.
12 FOO=bar 2>/dev/null
13
14 ### Redirect in subshell
15 FOO=$(echo foo 1>&2)
16 echo $FOO
17 # stdout:
18 # stderr: foo
19
20 ### Redirect in assignment
21 # dash captures stderr to a file here, which seems correct. Bash doesn't and
22 # just lets it go to actual stderr.
23 # For now we've settled on bash behavior, for compatibility?
24 FOO=$(echo foo 1>&2) 2>$TMP/no-command.txt
25 echo FILE=
26 cat $TMP/no-command.txt
27 echo "FOO=$FOO"
28 # OK dash/mksh stdout-json: "FILE=\nfoo\nFOO=\n"
29 # stdout-json: "FILE=\nFOO=\n"
30
31 ### Redirect in function body.
32 # Wow this is interesting, didn't know about it.
33 func() { echo hi; } 1>&2; func
34 # stderr: hi
35
36 ### Descriptor redirect with spaces
37 # Hm this seems like a failure of lookahead! The second thing should look to a
38 # file-like thing.
39 # I think this is a posix issue.
40 # tag: posix-issue
41 echo one 1>&2
42 echo two 1 >&2
43 echo three 1>& 2
44 # stderr-json: "one\ntwo 1\nthree\n"
45
46 ### Filename redirect with spaces
47 # This time 1 *is* a descriptor, not a word. If you add a space between 1 and
48 # >, it doesn't work.
49 echo two 1> $TMP/file-redir1.txt
50 cat $TMP/file-redir1.txt
51 # stdout: two
52
53 ### Quoted filename redirect with spaces
54 # POSIX makes node of this
55 echo two \1 > $TMP/file-redir2.txt
56 cat $TMP/file-redir2.txt
57 # stdout: two 1
58
59 ### Descriptor redirect with filename
60 # Should be a syntax error, but bash allows this.
61 echo one 1>&$TMP/nonexistent-filename__
62 # status: 2
63 # stdout-json: ""
64 # OK mksh status: 1
65 # BUG bash status: 0
66
67 ### redirect for loop
68 for i in $(seq 3)
69 do
70 echo $i
71 done > $TMP/redirect-for-loop.txt
72 cat $TMP/redirect-for-loop.txt
73 # stdout-json: "1\n2\n3\n"
74
75 ### Prefix redirect for loop -- not allowed
76 >$TMP/redirect2.txt for i in $(seq 3)
77 do
78 echo $i
79 done
80 cat $TMP/redirect2.txt
81 # status: 2
82 # OK mksh status: 1
83
84 ### Block redirect
85 # Suffix works, but prefix does NOT work.
86 # That comes from '| compound_command redirect_list' in the grammar!
87 { echo block-redirect; } > $TMP/br.txt
88 cat $TMP/br.txt | wc -c
89 # stdout: 15
90
91 ### Redirect echo to stderr, and then redirect all of stdout somewhere.
92 { echo foo 1>&2; echo 012345789; } > $TMP/block-stdout.txt
93 cat $TMP/block-stdout.txt | wc -c
94 # stderr: foo
95 # stdout: 10
96
97 ### Redirect in the middle of two assignments
98 FOO=foo >$TMP/out.txt BAR=bar printenv.py FOO BAR
99 tac $TMP/out.txt
100 # stdout-json: "bar\nfoo\n"
101
102 ### Redirect in the middle of a command
103 f=$TMP/out
104 echo -n 1 2 '3 ' > $f
105 echo -n 4 5 >> $f '6 '
106 echo -n 7 >> $f 8 '9 '
107 echo -n >> $f 1 2 '3 '
108 echo >> $f -n 4 5 '6 '
109 cat $f
110 # stdout-json: "1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 "
111
112 ### Named file descriptor
113 exec {myfd}> $TMP/named-fd.txt
114 echo named-fd-contents >& $myfd
115 cat $TMP/named-fd.txt
116 # stdout: named-fd-contents
117 # N-I dash/mksh stdout-json: ""
118
119
120