OILS / spec / here-doc.test.sh View on Github | oilshell.org

370 lines, 326 significant
1
2#### Here string
3cat <<< 'hi'
4## stdout-json: "hi\n"
5## N-I dash stdout-json: ""
6## N-I dash status: 2
7
8#### Here string with $
9cat <<< $'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.
16cat 0<<EOF
17one
18EOF
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?
24read_from_fd.py 8 8<<EOF
25here doc on descriptor
26EOF
27## stdout: 8: here doc on descriptor
28
29#### Multiple here docs with different descriptors
30read_from_fd.py 0 3 <<EOF 3<<EOF3
31fd0
32EOF
33fd3
34EOF3
35## STDOUT:
360: fd0
373: fd3
38## END
39
40#### Here doc with bad var delimiter
41# Most shells accept this, but OSH is stricter.
42cat <<${a}
43here
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.
51cat <<$(a)
52here
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
62echo hello >$TMP/hello.txt
63
64cat <<EOF <$TMP/hello.txt
65here
66EOF
67## stdout: hello
68
69#### < redirect and here doc -- last one wins
70
71echo hello >$TMP/hello.txt
72
73cat <$TMP/hello.txt <<EOF
74here
75EOF
76## stdout: here
77
78#### Here doc with var sub, command sub, arith sub
79var=v
80cat <<EOF
81var: ${var}
82command: $(echo hi)
83arith: $((1+2))
84EOF
85## STDOUT:
86var: v
87command: hi
88arith: 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!
94echo foo > _tmp/foo.txt
95echo bar > _tmp/bar.txt
96cat <<EOF 1>&2 _tmp/foo.txt - _tmp/bar.txt
97here
98EOF
99## STDERR:
100foo
101here
102bar
103## END
104
105#### Here doc line continuation
106cat <<EOF \
107; echo two
108one
109EOF
110## STDOUT:
111one
112two
113## END
114
115#### Here doc with quote expansion in terminator
116cat <<'EOF'"2"
117one
118two
119EOF2
120## stdout-json: "one\ntwo\n"
121
122#### Here doc with multiline double quoted string
123cat <<EOF; echo "two
124three"
125one
126EOF
127## STDOUT:
128one
129two
130three
131## END
132
133#### Two here docs -- first is ignored; second ones wins!
134<<EOF1 cat <<EOF2
135hello
136EOF1
137there
138EOF2
139## stdout: there
140
141#### Here doc with line continuation, then pipe. Syntax error.
142cat <<EOF \
1431
1442
1453
146EOF
147| tac
148## status: 2
149## OK mksh status: 1
150
151#### Here doc with pipe on first line
152cat <<EOF | tac
1531
1542
1553
156EOF
157## STDOUT:
1583
1592
1601
161## END
162
163#### Here doc with pipe continued on last line
164cat <<EOF |
1651
1662
1673
168EOF
169tac
170## STDOUT:
1713
1722
1731
174## END
175
176#### Here doc with builtin 'read'
177# read can't be run in a subshell.
178read v1 v2 <<EOF
179val1 val2
180EOF
181echo =$v1= =$v2=
182## stdout: =val1= =val2=
183
184#### Compound command here doc
185while read line; do
186 echo X $line
187done <<EOF
1881
1892
1903
191EOF
192## STDOUT:
193X 1
194X 2
195X 3
196## END
197
198
199#### Here doc in while condition and here doc in body
200while cat <<E1 && cat <<E2; do cat <<E3; break; done
2011
202E1
2032
204E2
2053
206E3
207## STDOUT:
2081
2092
2103
211## END
212
213#### Here doc in while condition and here doc in body on multiple lines
214while cat <<E1 && cat <<E2
2151
216E1
2172
218E2
219do
220 cat <<E3
2213
222E3
223 break
224done
225## STDOUT:
2261
2272
2283
229## END
230
231#### Here doc in while loop split up more
232while cat <<E1
2331
234E1
235
236cat <<E2
2372
238E2
239
240do
241 cat <<E3
2423
243E3
244 break
245done
246## STDOUT:
2471
2482
2493
250## END
251
252#### Mixing << and <<-
253cat <<-EOF; echo --; cat <<EOF2
254 one
255EOF
256two
257EOF2
258## stdout-json: "one\n--\ntwo\n"
259
260
261
262#### Two compound commands with two here docs
263while read line; do echo X $line; done <<EOF; echo ==; while read line; do echo Y $line; done <<EOF2
2641
2652
266EOF
2673
2684
269EOF2
270## stdout-json: "X 1\nX 2\n==\nY 3\nY 4\n"
271
272#### Function def and execution with here doc
273fun() { cat; } <<EOF; echo before; fun; echo after
2741
2752
276EOF
277## stdout-json: "before\n1\n2\nafter\n"
278
279#### Here doc as command prefix
280<<EOF tac
2811
2822
2833
284EOF
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
293cat <<EOF 1>&2
294out
295EOF
296## stderr: out
297
298#### here doc stripping tabs
299cat <<-EOF
300 1
301 2
302 3 # 2 tabs are both stripped
303 4 # spaces are preserved
304 EOF
305## STDOUT:
3061
3072
3083 # 2 tabs are both stripped
309 4 # spaces are preserved
310## END
311
312#### Here doc within subshell with boolean
313[[ $(cat <<EOF
314foo
315EOF
316) == foo ]]; echo $?
317## stdout: 0
318## N-I dash stdout: 127
319
320#### Here Doc in if condition
321if cat <<EOF; then
322here doc in IF CONDITION
323EOF
324 echo THEN executed
325fi
326## STDOUT:
327here doc in IF CONDITION
328THEN executed
329## END
330
331#### Nested here docs which are indented
332cat <<- EOF
333 outside
334 $(cat <<- INSIDE
335 inside
336INSIDE
337)
338EOF
339## STDOUT:
340outside
341inside
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.
347read_from_fd.py 3 3<<EOF3 | read_from_fd.py 0 5 5<<EOF5
348fd3
349EOF3
350fd5
351EOF5
352## STDOUT:
3530: 3: fd3
3545: 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.
360read_from_fd.py 3 3<<EOF3 |
361fd3
362EOF3
363read_from_fd.py 0 5 5<<EOF5
364fd5
365EOF5
366## STDOUT:
3670: 3: fd3
3685: fd5
369## END
370