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