1
2 #### Here string
3 cat <<< 'hi'
4 ## stdout-json: "hi\n"
5 ## N-I dash stdout-json: ""
6 ## N-I dash status: 2
7
8 #### Here string with $
9 cat <<< $'one\ntwo\n'
10 ## stdout-json: "one\ntwo\n\n"
11 ## N-I dash stdout-json: ""
12 ## N-I dash status: 2
13
14 #### Here redirect with explicit descriptor
15 # A space betwen 0 and <<EOF causes it to pass '0' as an arg to cat.
16 cat 0<<EOF
17 one
18 EOF
19 ## stdout: one
20
21 #### Here doc from another input file descriptor
22 # NOTE: OSH fails on descriptor 9, but not descriptor 8? Is this because of
23 # the Python VM? How to inspect state?
24 read_from_fd.py 8 8<<EOF
25 here doc on descriptor
26 EOF
27 ## stdout: 8: here doc on descriptor
28
29 #### Multiple here docs with different descriptors
30 read_from_fd.py 0 3 <<EOF 3<<EOF3
31 fd0
32 EOF
33 fd3
34 EOF3
35 ## STDOUT:
36 0: fd0
37 3: fd3
38 ## END
39
40 #### Here doc with bad var delimiter
41 # Most shells accept this, but OSH is stricter.
42 cat <<${a}
43 here
44 ${a}
45 ## stdout: here
46 ## OK osh stdout-json: ""
47 ## OK osh status: 2
48
49 #### Here doc with bad comsub delimiter
50 # bash is OK with this; dash isn't. Should be a parse error.
51 cat <<$(a)
52 here
53 $(a)
54 ## stdout-json: ""
55 ## status: 2
56 ## BUG bash stdout: here
57 ## BUG bash status: 0
58 ## OK mksh status: 1
59
60 #### Here doc and < redirect -- last one wins
61 echo hello >$TMP/hello.txt # temporary fix
62 cat <<EOF <$TMP/hello.txt
63 here
64 EOF
65 ## stdout: hello
66
67 #### < redirect and here doc -- last one wins
68 cat <$TMP/hello.txt <<EOF
69 here
70 EOF
71 ## stdout: here
72
73 #### Here doc with var sub, command sub, arith sub
74 var=v
75 cat <<EOF
76 var: ${var}
77 command: $(echo hi)
78 arith: $((1+2))
79 EOF
80 ## STDOUT:
81 var: v
82 command: hi
83 arith: 3
84 ## END
85
86 #### Here doc in middle. And redirects in the middle.
87 # This isn't specified by the POSIX grammar, but it's accepted by both dash and
88 # bash!
89 echo foo > _tmp/foo.txt
90 echo bar > _tmp/bar.txt
91 cat <<EOF 1>&2 _tmp/foo.txt - _tmp/bar.txt
92 here
93 EOF
94 ## STDERR:
95 foo
96 here
97 bar
98 ## END
99
100 #### Here doc line continuation
101 cat <<EOF \
102 ; echo two
103 one
104 EOF
105 ## STDOUT:
106 one
107 two
108 ## END
109
110 #### Here doc with quote expansion in terminator
111 cat <<'EOF'"2"
112 one
113 two
114 EOF2
115 ## stdout-json: "one\ntwo\n"
116
117 #### Here doc with multiline double quoted string
118 cat <<EOF; echo "two
119 three"
120 one
121 EOF
122 ## STDOUT:
123 one
124 two
125 three
126 ## END
127
128 #### Two here docs -- first is ignored; second ones wins!
129 <<EOF1 cat <<EOF2
130 hello
131 EOF1
132 there
133 EOF2
134 ## stdout: there
135
136 #### Here doc with line continuation, then pipe. Syntax error.
137 cat <<EOF \
138 1
139 2
140 3
141 EOF
142 | tac
143 ## status: 2
144 ## OK mksh status: 1
145
146 #### Here doc with pipe on first line
147 cat <<EOF | tac
148 1
149 2
150 3
151 EOF
152 ## STDOUT:
153 3
154 2
155 1
156 ## END
157
158 #### Here doc with pipe continued on last line
159 cat <<EOF |
160 1
161 2
162 3
163 EOF
164 tac
165 ## STDOUT:
166 3
167 2
168 1
169 ## END
170
171 #### Here doc with builtin 'read'
172 # read can't be run in a subshell.
173 read v1 v2 <<EOF
174 val1 val2
175 EOF
176 echo =$v1= =$v2=
177 ## stdout: =val1= =val2=
178
179 #### Compound command here doc
180 while read line; do
181 echo X $line
182 done <<EOF
183 1
184 2
185 3
186 EOF
187 ## STDOUT:
188 X 1
189 X 2
190 X 3
191 ## END
192
193
194 #### Here doc in while condition and here doc in body
195 while cat <<E1 && cat <<E2; do cat <<E3; break; done
196 1
197 E1
198 2
199 E2
200 3
201 E3
202 ## STDOUT:
203 1
204 2
205 3
206 ## END
207
208 #### Here doc in while condition and here doc in body on multiple lines
209 while cat <<E1 && cat <<E2
210 1
211 E1
212 2
213 E2
214 do
215 cat <<E3
216 3
217 E3
218 break
219 done
220 ## STDOUT:
221 1
222 2
223 3
224 ## END
225
226 #### Here doc in while loop split up more
227 while cat <<E1
228 1
229 E1
230
231 cat <<E2
232 2
233 E2
234
235 do
236 cat <<E3
237 3
238 E3
239 break
240 done
241 ## STDOUT:
242 1
243 2
244 3
245 ## END
246
247 #### Mixing << and <<-
248 cat <<-EOF; echo --; cat <<EOF2
249 one
250 EOF
251 two
252 EOF2
253 ## stdout-json: "one\n--\ntwo\n"
254
255
256
257 #### Two compound commands with two here docs
258 while read line; do echo X $line; done <<EOF; echo ==; while read line; do echo Y $line; done <<EOF2
259 1
260 2
261 EOF
262 3
263 4
264 EOF2
265 ## stdout-json: "X 1\nX 2\n==\nY 3\nY 4\n"
266
267 #### Function def and execution with here doc
268 fun() { cat; } <<EOF; echo before; fun; echo after
269 1
270 2
271 EOF
272 ## stdout-json: "before\n1\n2\nafter\n"
273
274 #### Here doc as command prefix
275 <<EOF tac
276 1
277 2
278 3
279 EOF
280 ## stdout-json: "3\n2\n1\n"
281
282 # NOTE that you can have redirection AFTER the here doc thing. And you don't
283 # need a space! Those are operators.
284 #
285 # POSIX doesn't seem to have this? They have io_file, which is for
286 # filenames, and io_here, which is here doc. But about 1>&2 syntax? Geez.
287 #### Redirect after here doc
288 cat <<EOF 1>&2
289 out
290 EOF
291 ## stderr: out
292
293 #### here doc stripping tabs
294 cat <<-EOF
295 1
296 2
297 3 # 2 tabs are both stripped
298 4 # spaces are preserved
299 EOF
300 ## STDOUT:
301 1
302 2
303 3 # 2 tabs are both stripped
304 4 # spaces are preserved
305 ## END
306
307 #### Here doc within subshell with boolean
308 [[ $(cat <<EOF
309 foo
310 EOF
311 ) == foo ]]; echo $?
312 ## stdout: 0
313 ## N-I dash stdout: 127
314
315 #### Here Doc in if condition
316 if cat <<EOF; then
317 here doc in IF CONDITION
318 EOF
319 echo THEN executed
320 fi
321 ## STDOUT:
322 here doc in IF CONDITION
323 THEN executed
324 ## END
325
326 #### Nested here docs which are indented
327 cat <<- EOF
328 outside
329 $(cat <<- INSIDE
330 inside
331 INSIDE
332 )
333 EOF
334 ## STDOUT:
335 outside
336 inside
337 ## END
338
339 #### Multiple here docs in pipeline
340 # SKIPPED: hangs with osh on Debian
341 # The second instance reads its stdin from the pipe, and fd 5 from a here doc.
342 read_from_fd.py 3 3<<EOF3 | read_from_fd.py 0 5 5<<EOF5
343 fd3
344 EOF3
345 fd5
346 EOF5
347 ## STDOUT:
348 0: 3: fd3
349 5: fd5
350 ## END
351
352 #### Multiple here docs in pipeline on multiple lines
353 # SKIPPED: hangs with osh on Debian
354 # The second instance reads its stdin from the pipe, and fd 5 from a here doc.
355 read_from_fd.py 3 3<<EOF3 |
356 fd3
357 EOF3
358 read_from_fd.py 0 5 5<<EOF5
359 fd5
360 EOF5
361 ## STDOUT:
362 0: 3: fd3
363 5: fd5
364 ## END
365