OILS / spec / here-doc.test.sh View on Github | oils.pub

411 lines, 360 significant
1## oils_failures_allowed: 2
2## compare_shells: dash bash mksh
3
4#### Here string
5cat <<< 'hi'
6## STDOUT:
7hi
8## END
9## N-I dash stdout-json: ""
10## N-I dash status: 2
11
12#### Here string with $
13cat <<< $'one\ntwo\n'
14## STDOUT:
15one
16two
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.
24cat 0<<EOF
25one
26EOF
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?
32read_from_fd.py 8 8<<EOF
33here doc on descriptor
34EOF
35## stdout: 8: here doc on descriptor
36
37#### Multiple here docs with different descriptors
38read_from_fd.py 0 3 <<EOF 3<<EOF3
39fd0
40EOF
41fd3
42EOF3
43## STDOUT:
440: fd0
453: fd3
46## END
47
48#### Here doc with bad var delimiter
49# Most shells accept this, but OSH is stricter.
50cat <<${a}
51here
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.
59cat <<$(a)
60here
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
70echo hello >$TMP/hello.txt
71
72cat <<EOF <$TMP/hello.txt
73here
74EOF
75## stdout: hello
76
77#### < redirect and here doc -- last one wins
78
79echo hello >$TMP/hello.txt
80
81cat <$TMP/hello.txt <<EOF
82here
83EOF
84## stdout: here
85
86#### Here doc with var sub, command sub, arith sub
87var=v
88cat <<EOF
89var: ${var}
90command: $(echo hi)
91arith: $((1+2))
92EOF
93## STDOUT:
94var: v
95command: hi
96arith: 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!
102echo foo > foo.txt
103echo bar > bar.txt
104cat <<EOF 1>&2 foo.txt - bar.txt
105here
106EOF
107## STDERR:
108foo
109here
110bar
111## END
112
113#### Here doc line continuation
114cat <<EOF \
115; echo two
116one
117EOF
118## STDOUT:
119one
120two
121## END
122
123#### Here doc with quote expansion in terminator
124cat <<'EOF'"2"
125one
126two
127EOF2
128## STDOUT:
129one
130two
131## END
132
133#### Here doc with multiline double quoted string
134cat <<EOF; echo "two
135three"
136one
137EOF
138## STDOUT:
139one
140two
141three
142## END
143
144#### Two here docs -- first is ignored; second ones wins!
145<<EOF1 cat <<EOF2
146hello
147EOF1
148there
149EOF2
150## stdout: there
151
152#### Here doc with line continuation, then pipe. Syntax error.
153cat <<EOF \
1541
1552
1563
157EOF
158| tac
159## status: 2
160## OK mksh status: 1
161
162#### Here doc with pipe on first line
163cat <<EOF | tac
1641
1652
1663
167EOF
168## STDOUT:
1693
1702
1711
172## END
173
174#### Here doc with pipe continued on last line
175cat <<EOF |
1761
1772
1783
179EOF
180tac
181## STDOUT:
1823
1832
1841
185## END
186
187#### Here doc with builtin 'read'
188# read can't be run in a subshell.
189read v1 v2 <<EOF
190val1 val2
191EOF
192echo =$v1= =$v2=
193## stdout: =val1= =val2=
194
195#### Compound command here doc
196while read line; do
197 echo X $line
198done <<EOF
1991
2002
2013
202EOF
203## STDOUT:
204X 1
205X 2
206X 3
207## END
208
209
210#### Here doc in while condition and here doc in body
211while cat <<E1 && cat <<E2; do cat <<E3; break; done
2121
213E1
2142
215E2
2163
217E3
218## STDOUT:
2191
2202
2213
222## END
223
224#### Here doc in while condition and here doc in body on multiple lines
225while cat <<E1 && cat <<E2
2261
227E1
2282
229E2
230do
231 cat <<E3
2323
233E3
234 break
235done
236## STDOUT:
2371
2382
2393
240## END
241
242#### Here doc in while loop split up more
243while cat <<E1
2441
245E1
246
247cat <<E2
2482
249E2
250
251do
252 cat <<E3
2533
254E3
255 break
256done
257## STDOUT:
2581
2592
2603
261## END
262
263#### Mixing << and <<-
264cat <<-EOF; echo --; cat <<EOF2
265 one
266EOF
267two
268EOF2
269## STDOUT:
270one
271--
272two
273## END
274
275
276
277#### Two compound commands with two here docs
278while read line; do echo X $line; done <<EOF; echo ==; while read line; do echo Y $line; done <<EOF2
2791
2802
281EOF
2823
2834
284EOF2
285## STDOUT:
286X 1
287X 2
288==
289Y 3
290Y 4
291## END
292
293#### Function def and execution with here doc
294fun() { cat; } <<EOF; echo before; fun; echo after
2951
2962
297EOF
298## STDOUT:
299before
3001
3012
302after
303## END
304
305#### Here doc as command prefix
306<<EOF tac
3071
3082
3093
310EOF
311## STDOUT:
3123
3132
3141
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
323cat <<EOF 1>&2
324out
325EOF
326## stderr: out
327
328#### here doc stripping tabs
329cat <<-EOF
330 1
331 2
332 3 # 2 tabs are both stripped
333 4 # spaces are preserved
334 EOF
335## STDOUT:
3361
3372
3383 # 2 tabs are both stripped
339 4 # spaces are preserved
340## END
341
342#### Here doc within subshell with boolean
343[[ $(cat <<EOF
344foo
345EOF
346) == foo ]]; echo $?
347## stdout: 0
348## N-I dash stdout: 127
349
350#### Here Doc in if condition
351if cat <<EOF; then
352here doc in IF CONDITION
353EOF
354 echo THEN executed
355fi
356## STDOUT:
357here doc in IF CONDITION
358THEN executed
359## END
360
361#### Nested here docs which are indented
362cat <<- EOF
363 outside
364 $(cat <<- INSIDE
365 inside
366INSIDE
367)
368EOF
369## STDOUT:
370outside
371inside
372## END
373
374#### Multiple here docs in pipeline
375case $SH in *osh) exit ;; esac
376
377# The second instance reads its stdin from the pipe, and fd 5 from a here doc.
378read_from_fd.py 3 3<<EOF3 | read_from_fd.py 0 5 5<<EOF5
379fd3
380EOF3
381fd5
382EOF5
383
384echo ok
385
386## STDOUT:
3870: 3: fd3
3885: fd5
389ok
390## END
391
392#### Multiple here docs in pipeline on multiple lines
393case $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.
397read_from_fd.py 3 3<<EOF3 |
398fd3
399EOF3
400read_from_fd.py 0 5 5<<EOF5
401fd5
402EOF5
403
404echo ok
405
406## STDOUT:
4070: 3: fd3
4085: fd5
409ok
410## END
411