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