xref: /titanic_51/usr/src/lib/libshell/common/tests/heredoc.sh (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4*3e14f97fSRoger A. Faulkner#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6da2e3ebdSchin#                  Common Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10da2e3ebdSchin#            http://www.opensource.org/licenses/cpl1.0.txt             #
11da2e3ebdSchin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12da2e3ebdSchin#                                                                      #
13da2e3ebdSchin#              Information and Software Systems Research               #
14da2e3ebdSchin#                            AT&T Research                             #
15da2e3ebdSchin#                           Florham Park NJ                            #
16da2e3ebdSchin#                                                                      #
17da2e3ebdSchin#                  David Korn <dgk@research.att.com>                   #
18da2e3ebdSchin#                                                                      #
19da2e3ebdSchin########################################################################
20da2e3ebdSchinfunction err_exit
21da2e3ebdSchin{
22da2e3ebdSchin	print -u2 -n "\t"
23da2e3ebdSchin	print -u2 -r ${Command}[$1]: "${@:2}"
24da2e3ebdSchin	let Errors+=1
25da2e3ebdSchin}
26da2e3ebdSchinalias err_exit='err_exit $LINENO'
27da2e3ebdSchin
28da2e3ebdSchinCommand=${0##*/}
29da2e3ebdSchininteger Errors=0
3034f9b3eeSRoland Mainz
3134f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3234f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT
3334f9b3eeSRoland Mainz
3434f9b3eeSRoland Mainzf=$tmp/here1
3534f9b3eeSRoland Mainzg=$tmp/here2
36da2e3ebdSchincat > $f <<!
37da2e3ebdSchinhello world
38da2e3ebdSchin!
39da2e3ebdSchinif	[[ $(<$f) != 'hello world' ]]
40da2e3ebdSchinthen	err_exit "'hello world' here doc not working"
41da2e3ebdSchinfi
42da2e3ebdSchincat > $g <<\!
43da2e3ebdSchinhello world
44da2e3ebdSchin!
45da2e3ebdSchincmp $f $g 2> /dev/null || err_exit "'hello world' quoted here doc not working"
46da2e3ebdSchincat > $g <<- !
47da2e3ebdSchin	hello world
48da2e3ebdSchin!
49da2e3ebdSchincmp $f $g 2> /dev/null || err_exit "'hello world' tabbed here doc not working"
50da2e3ebdSchincat > $g <<- \!
51da2e3ebdSchin	hello world
52da2e3ebdSchin!
53da2e3ebdSchincmp $f $g 2> /dev/null || err_exit "'hello world' quoted tabbed here doc not working"
54da2e3ebdSchinx=hello
55da2e3ebdSchincat > $g <<!
56da2e3ebdSchin$x world
57da2e3ebdSchin!
58da2e3ebdSchincmp $f $g 2> /dev/null || err_exit "'$x world' here doc not working"
59da2e3ebdSchincat > $g <<!
60da2e3ebdSchin$(print hello) world
61da2e3ebdSchin!
62da2e3ebdSchincmp $f $g 2> /dev/null || err_exit "'$(print hello) world' here doc not working"
63da2e3ebdSchincat > $f <<\!!
64da2e3ebdSchin!@#$%%^^&*()_+~"::~;'`<>?/.,{}[]
65da2e3ebdSchin!!
66da2e3ebdSchinif	[[ $(<$f) != '!@#$%%^^&*()_+~"::~;'\''`<>?/.,{}[]' ]]
67da2e3ebdSchinthen	err_exit "'hello world' here doc not working"
68da2e3ebdSchinfi
69da2e3ebdSchincat > $g <<!!
70da2e3ebdSchin!@#\$%%^^&*()_+~"::~;'\`<>?/.,{}[]
71da2e3ebdSchin!!
72da2e3ebdSchincmp $f $g 2> /dev/null || err_exit "unquoted here doc not working"
73da2e3ebdSchinexec 3<<!
74da2e3ebdSchin	foo
75da2e3ebdSchin!
76da2e3ebdSchinif	[[ $(<&3) != '	foo' ]]
77da2e3ebdSchinthen	err_exit "leading tabs stripped with <<!"
78da2e3ebdSchinfi
79da2e3ebdSchin$SHELL -c "
80da2e3ebdSchineval `echo 'cat <<x'` "|| err_exit "eval `echo 'cat <<x'` core dumps"
81da2e3ebdSchincat > /dev/null <<EOF # comments should not cause core dumps
82da2e3ebdSchinabc
83da2e3ebdSchinEOF
84da2e3ebdSchincat >$g << :
85da2e3ebdSchin:
86da2e3ebdSchin:
87da2e3ebdSchincmp /dev/null $g 2> /dev/null || err_exit "empty here doc not working"
88da2e3ebdSchinx=$(print $( cat <<HUP
89da2e3ebdSchinhello
90da2e3ebdSchinHUP
91da2e3ebdSchin)
92da2e3ebdSchin)
93da2e3ebdSchinif	[[ $x != hello ]]
94da2e3ebdSchinthen	err_exit "here doc inside command sub not working"
95da2e3ebdSchinfi
96da2e3ebdSchiny=$(cat <<!
97da2e3ebdSchin${x:+${x}}
98da2e3ebdSchin!
99da2e3ebdSchin)
100da2e3ebdSchinif	[[ $y != "${x:+${x}}" ]]
101da2e3ebdSchinthen	err_exit '${x:+${x}} not working in here document'
102da2e3ebdSchinfi
103da2e3ebdSchin$SHELL -c '
104da2e3ebdSchinx=0
105da2e3ebdSchinwhile (( x < 100 ))
106da2e3ebdSchindo	((x = x+1))
107da2e3ebdSchin	cat << EOF
108da2e3ebdSchinEOF
109da2e3ebdSchindone
110da2e3ebdSchin' 2> /dev/null  || err_exit '100 empty here docs fails'
111da2e3ebdSchin{
112da2e3ebdSchin	print 'builtin -d cat
113da2e3ebdSchin	cat <<- EOF'
114da2e3ebdSchin	for ((i=0; i < 100; i++))
115da2e3ebdSchin	do print XXXXXXXXXXXXXXXXXXXX
116da2e3ebdSchin	done
117da2e3ebdSchin	print ' XXX$(date)XXXX
118da2e3ebdSchin	EOF'
119da2e3ebdSchin} > $f
120da2e3ebdSchinchmod +x "$f"
121da2e3ebdSchin$SHELL "$f" > /dev/null  || err_exit "large here-doc with command substitution fails"
122da2e3ebdSchinx=$(/bin/cat <<!
123da2e3ebdSchin$0
124da2e3ebdSchin!
125da2e3ebdSchin)
126da2e3ebdSchin[[ "$x" == "$0" ]] || err_exit '$0 not correct inside here documents'
127da2e3ebdSchin$SHELL -c 'x=$(
128da2e3ebdSchincat << EOF
129da2e3ebdSchinEOF)' 2> /dev/null || err_exit 'here-doc cannot be terminated by )'
130da2e3ebdSchinif	[[ $( IFS=:;cat <<-!
131da2e3ebdSchin			$IFS$(print hi)$IFS
132da2e3ebdSchin		!) != :hi: ]]
133da2e3ebdSchinthen	err_exit '$IFS unset by command substitution in here docs'
134da2e3ebdSchinfi
135da2e3ebdSchinif	x=$($SHELL -c 'cat <<< "hello world"' 2> /dev/null)
136da2e3ebdSchinthen	[[ $x == 'hello world' ]] || err_exit '<<< documents not working'
137da2e3ebdSchin	x=$($SHELL -c 'v="hello  world";cat <<< $v' 2> /dev/null)
138da2e3ebdSchin	[[ $x == 'hello  world' ]] || err_exit '<<< documents with $x not working'
139da2e3ebdSchin	x=$($SHELL -c 'v="hello  world";cat <<< "$v"' 2> /dev/null)
140da2e3ebdSchin	[[ $x == 'hello  world' ]] || err_exit '<<< documents with $x not working'
141da2e3ebdSchinelse	err_exit '<<< syntax not supported'
142da2e3ebdSchinfi
143da2e3ebdSchinif	[[ $(cat << EOF #testing
144da2e3ebdSchin#abc
145da2e3ebdSchinabc
146da2e3ebdSchinEOF) != $'#abc\nabc' ]]
147da2e3ebdSchinthen	err_exit 'comments not preserved in here-documents'
148da2e3ebdSchinfi
149da2e3ebdSchincat  > "$f" <<- '!!!!'
150da2e3ebdSchin	builtin cat
151da2e3ebdSchin	: << EOF
152da2e3ebdSchin	$PWD
153da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
154da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
155da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
156da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
157da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
158da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
159da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
160da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
161da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
162da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
163da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
164da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
165da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
166da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
167da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
168da2e3ebdSchin	EOF
169da2e3ebdSchin	command exec 3>&- 4>&- 5>&- 6>&- 7>&- 8>&- 9>&-
170da2e3ebdSchin	x=abc
171da2e3ebdSchin	cat << EOF
172da2e3ebdSchin	$x
173da2e3ebdSchin	EOF
174da2e3ebdSchin!!!!
175da2e3ebdSchinchmod 755 "$f"
176da2e3ebdSchinif	[[ $($SHELL  "$f") != abc ]]
177da2e3ebdSchinthen	err_exit	'here document descritor was closed'
178da2e3ebdSchinfi
179da2e3ebdSchincat  > "$f" <<- '!!!!'
180da2e3ebdSchin	exec 0<&-
181da2e3ebdSchin	foobar()
182da2e3ebdSchin	{
183da2e3ebdSchin		/bin/cat <<- !
184da2e3ebdSchin		foobar
185da2e3ebdSchin		!
186da2e3ebdSchin	}
187da2e3ebdSchin	: << EOF
188da2e3ebdSchin	$PWD
189da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
190da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
191da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
192da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
193da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
194da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
195da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
196da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
197da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
198da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
199da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
200da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
201da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
202da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
203da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
204da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
205da2e3ebdSchin	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
206da2e3ebdSchin	EOF
207da2e3ebdSchin	print -r -- "$(foobar)"
208da2e3ebdSchin!!!!
209da2e3ebdSchinif	[[ $($SHELL  "$f") != foobar ]]
210da2e3ebdSchinthen	err_exit	'here document with stdin closed failed'
211da2e3ebdSchinfi
212da2e3ebdSchinprintf $'cat   <<# \\!!!\n\thello\n\t\tworld\n!!!' > $f
213da2e3ebdSchin[[ $($SHELL "$f") == $'hello\n\tworld' ]] || err_exit "<<# not working for quoted here documents"
214da2e3ebdSchinprintf $'w=world;cat   <<# !!!\n\thello\n\t\t$w\n!!!' > $f
215da2e3ebdSchin[[ $($SHELL "$f") == $'hello\n\tworld' ]] || err_exit "<<# not working for non-quoted here documents"
2167c2fbfb3SApril Chin[[ $( $SHELL  <<- \++++
2177c2fbfb3SApril Chin	S=( typeset a )
2187c2fbfb3SApril Chin	function S.a.get
2197c2fbfb3SApril Chin	{
2207c2fbfb3SApril Chin	     .sh.value=$__a
2217c2fbfb3SApril Chin	}
2227c2fbfb3SApril Chin	__a=1234
2237c2fbfb3SApril Chin	cat <<-EOF
2247c2fbfb3SApril Chin	${S.a}
2257c2fbfb3SApril Chin	EOF
2267c2fbfb3SApril Chin++++
2277c2fbfb3SApril Chin) == 1234 ]]  2> /dev/null || err_exit 'here document with get discipline failed'
2287c2fbfb3SApril Chin[[ $($SHELL -c 'g(){ print ok;}; cat <<- EOF
2297c2fbfb3SApril Chin	${ g;}
2307c2fbfb3SApril Chin	EOF
2317c2fbfb3SApril Chin	' 2> /dev/null) == ok ]] || err_exit '${ command;} not working in heredoc'
23234f9b3eeSRoland Mainzscript=$f
23334f9b3eeSRoland Mainz{
23434f9b3eeSRoland Mainzfor ((i=0; i < 406; i++))
23534f9b3eeSRoland Mainzdo	print ': 23456789012345678'
23634f9b3eeSRoland Mainzdone
23734f9b3eeSRoland Mainzprint : 123456789123
23834f9b3eeSRoland Mainzcat <<- \EOF
23934f9b3eeSRoland Mainzeval "$(
24034f9b3eeSRoland Mainz	{ cat                                 ; } <<MARKER
24134f9b3eeSRoland Mainz	  print  hello
24234f9b3eeSRoland Mainz	MARKER
24334f9b3eeSRoland Mainz)"
24434f9b3eeSRoland MainzEOF
24534f9b3eeSRoland Mainz} > $script
24634f9b3eeSRoland Mainzchmod +x $script
24734f9b3eeSRoland Mainz[[ $($SHELL $script) == hello ]] 2> /dev/null || err_exit 'heredoc embeded in command substitution fails at buffer boundary'
24834f9b3eeSRoland Mainz
24934f9b3eeSRoland Mainzgot=$( cat << EOF
25034f9b3eeSRoland Mainz\
25134f9b3eeSRoland Mainzabc
25234f9b3eeSRoland MainzEOF)
25334f9b3eeSRoland Mainz[[ $got == abc ]] || err_exit 'line continuation at start of buffer not working'
25434f9b3eeSRoland Mainz
255da2e3ebdSchinexit $((Errors))
256