1 #!/bin/bash
2
3 ### Here redirect with explicit descriptor
4 # A space betwen 0 and <<EOF causes it to pass '0' as an arg to cat.
5 cat 0<<EOF
6 one
7 EOF
8 # stdout: one
9
10 ### Here doc from another input file descriptor
11 # NOTE: dash seemed to fail on descriptor 99, but descriptor 5 works.
12 tests/read_from_fd.py 5 5<<EOF
13 fd5
14 EOF
15 # stdout: 5: fd5
16
17 ### Multiple here docs with different descriptors
18 tests/read_from_fd.py 0 3 <<EOF 3<<EOF3
19 fd0
20 EOF
21 fd3
22 EOF3
23 # stdout-json: "0: fd0\n3: fd3\n"
24
25 ### Multiple here docs in pipeline
26 # The second instance reads its stdin from the pipe, and fd 5 from a here doc.
27 tests/read_from_fd.py 3 3<<EOF3 | tests/read_from_fd.py 0 5 5<<EOF5
28 fd3
29 EOF3
30 fd5
31 EOF5
32 # stdout-json: "0: 3: fd3\n5: fd5\n"
33
34 ### Multiple here docs in pipeline on multiple lines
35 # The second instance reads its stdin from the pipe, and fd 5 from a here doc.
36 tests/read_from_fd.py 3 3<<EOF3 |
37 fd3
38 EOF3
39 tests/read_from_fd.py 0 5 5<<EOF5
40 fd5
41 EOF5
42 # stdout-json: "0: 3: fd3\n5: fd5\n"
43
44 ### Here doc with bad var delimiter
45 cat <<${a}
46 here
47 ${a}
48 # stdout: here
49
50 ### Here doc with bad comsub delimiter
51 # bash is OK with this; dash isn't. Should be a parse error.
52 cat <<$(a)
53 here
54 $(a)
55 # stdout-json: ""
56 # status: 2
57 # BUG bash stdout: here
58 # BUG bash status: 0
59 # OK mksh status: 1
60
61 ### Here doc and < redirect -- last one wins
62 echo hello >tests/hello.txt # temporary fix
63 cat <<EOF <tests/hello.txt
64 here
65 EOF
66 # stdout: hello
67
68 ### < redirect and here doc -- last one wins
69 cat <tests/hello.txt <<EOF
70 here
71 EOF
72 # stdout: here
73
74 ### Here doc with var sub, command sub, arith sub
75 var=v
76 cat <<EOF
77 var: ${var}
78 command: $(echo hi)
79 arith: $((1+2))
80 EOF
81 # stdout-json: "var: v\ncommand: hi\narith: 3\n"
82
83 ### Here doc in middle. And redirects in the middle.
84 # This isn't specified by the POSIX grammar, but it's accepted by both dash and
85 # bash!
86 echo foo > _tmp/foo.txt
87 echo bar > _tmp/bar.txt
88 cat <<EOF 1>&2 _tmp/foo.txt - _tmp/bar.txt
89 here
90 EOF
91 # stderr-json: "foo\nhere\nbar\n"
92
93 ### Here doc line continuation
94 cat <<EOF \
95 ; echo two
96 one
97 EOF
98 # stdout-json: "one\ntwo\n"
99
100 ### Here doc with quote expansion in terminator
101 cat <<'EOF'"2"
102 one
103 two
104 EOF2
105 # stdout-json: "one\ntwo\n"
106
107 ### Here doc with multiline double quoted string
108 cat <<EOF; echo "two
109 three"
110 one
111 EOF
112 # stdout-json: "one\ntwo\nthree\n"
113
114 ### Two here docs -- first is ignored; second ones wins!
115 <<EOF1 cat <<EOF2
116 hello
117 EOF1
118 there
119 EOF2
120 # stdout: there
121
122 ### Here doc with line continuation, then pipe. Syntax error.
123 cat <<EOF \
124 1
125 2
126 3
127 EOF
128 | tac
129 # status: 2
130 # OK mksh status: 1
131
132 ### Here doc with pipe on first line
133 cat <<EOF | tac
134 1
135 2
136 3
137 EOF
138 # stdout-json: "3\n2\n1\n"
139
140 ### Here doc with pipe continued on last line
141 cat <<EOF |
142 1
143 2
144 3
145 EOF
146 tac
147 # stdout-json: "3\n2\n1\n"
148
149 ### Here doc with builtin 'read'
150 # read can't be run in a subshell.
151 read v1 v2 <<EOF
152 val1 val2
153 EOF
154 echo =$v1= =$v2=
155 # stdout: =val1= =val2=
156
157 ### Compound command here doc
158 while read line; do
159 echo X $line
160 done <<EOF
161 1
162 2
163 3
164 EOF
165 # stdout-json: "X 1\nX 2\nX 3\n"
166
167
168 ### Here doc in while condition and here doc in body
169 while cat <<E1 && cat <<E2; do cat <<E3; break; done
170 1
171 E1
172 2
173 E2
174 3
175 E3
176 # stdout-json: "1\n2\n3\n"
177
178 ### Here doc in while condition and here doc in body on multiple lines
179 while cat <<E1 && cat <<E2
180 1
181 E1
182 2
183 E2
184 do
185 cat <<E3
186 3
187 E3
188 break
189 done
190 # stdout-json: "1\n2\n3\n"
191
192 ### Here doc in while loop split up more
193 while cat <<E1
194 1
195 E1
196
197 cat <<E2
198 2
199 E2
200
201 do
202 cat <<E3
203 3
204 E3
205 break
206 done
207 # stdout-json: "1\n2\n3\n"
208
209 ### Mixing << and <<-
210 cat <<-EOF; echo --; cat <<EOF2
211 one
212 EOF
213 two
214 EOF2
215 # stdout-json: "one\n--\ntwo\n"
216
217
218
219 ### Two compound commands with two here docs
220 while read line; do echo X $line; done <<EOF; echo ==; while read line; do echo Y $line; done <<EOF2
221 1
222 2
223 EOF
224 3
225 4
226 EOF2
227 # stdout-json: "X 1\nX 2\n==\nY 3\nY 4\n"
228
229 ### Function def and execution with here doc
230 func() { cat; } <<EOF; echo before; func; echo after
231 1
232 2
233 EOF
234 # stdout-json: "before\n1\n2\nafter\n"
235
236 ### Here doc as command prefix
237 <<EOF tac
238 1
239 2
240 3
241 EOF
242 # stdout-json: "3\n2\n1\n"
243
244 # NOTE that you can have redirection AFTER the here doc thing. And you don't
245 # need a space! Those are operators.
246 #
247 # POSIX doesn't seem to have this? They have io_file, which is for
248 # filenames, and io_here, which is here doc. But about 1>&2 syntax? Geez.
249 ### Redirect after here doc
250 cat <<EOF 1>&2
251 out
252 EOF
253 # stderr: out
254
255 ### here doc stripping tabs
256 cat <<-EOF
257 1
258 2
259 3
260 EOF
261 # stdout-json: "1\n2\n 3\n"
262
263 ### Here doc within subshell with boolean
264 [[ $(cat <<EOF
265 foo
266 EOF
267 ) == foo ]]; echo $?
268 # stdout: 0
269 # N-I dash stdout: 127