1# $NetBSD: t_cmdsub.sh,v 1.4 2016/04/04 12:40:13 christos Exp $ 2# 3# Copyright (c) 2016 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27# the implementation of "sh" to test 28: ${TEST_SH:="/bin/sh"} 29 30# 31# This file tests command substitutions ( `...` and $( ... ) ) 32# 33# CAUTION: 34# Be careful attempting running these tests outside the ATF environment 35# Some of the tests run "rm *" in the current directory to clean up 36# An ATF test directory should be empty already, outside ATF, anything 37 38atf_test_case a_basic_cmdsub 39a_basic_cmdsub_head() { 40 atf_set "descr" 'Test operation of simple $( ) substitutions' 41} 42a_basic_cmdsub_body() { 43 atf_check -s exit:0 -o match:'Result is true today' -e empty \ 44 ${TEST_SH} -c \ 45 'echo Result is $( true && echo true || echo false ) today' 46 47 atf_check -s exit:0 -o match:'Result is false today' -e empty \ 48 ${TEST_SH} -c \ 49 'echo Result is $( false && echo true || echo false ) today' 50 51 atf_check -s exit:0 -o match:'aaabbbccc' -e empty \ 52 ${TEST_SH} -c 'echo aaa$( echo bbb )ccc' 53 atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \ 54 ${TEST_SH} -c 'echo aaa$( echo bbb ccc )ddd' 55 atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \ 56 ${TEST_SH} -c 'echo aaa$( echo bbb; echo ccc )ddd' 57 atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \ 58 ${TEST_SH} -c 'echo "aaa$( echo bbb; echo ccc )ddd"' 59 60 atf_check -s exit:0 -o inline:'some string\n' -e empty \ 61 ${TEST_SH} -c 'X=$( echo some string ); echo "$X"' 62 atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \ 63 ${TEST_SH} -c 'X=$( echo "weird; string *" ); echo "$X"' 64 65 rm -f * 2>/dev/null || : 66 for f in file-1 file-2 67 do 68 cp /dev/null "$f" 69 done 70 71 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 72 ${TEST_SH} -c 'echo Found $( echo * )' 73 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 74 ${TEST_SH} -c 'echo Found "$( echo * )"' 75 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 76 ${TEST_SH} -c 'echo Found $('" echo '*' )" 77 atf_check -s exit:0 -o match:'Found \*' -e empty \ 78 ${TEST_SH} -c 'echo Found "$('" echo '*' "')"' 79 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 80 ${TEST_SH} -c 'echo Found $('" echo \\* )" 81 atf_check -s exit:0 -o match:'Found \*' -e empty \ 82 ${TEST_SH} -c 'echo Found "$('" echo \\* )"\" 83} 84 85atf_test_case b_basic_backticks 86b_basic_backticks_head() { 87 atf_set "descr" 'Test operation of old style ` ` substitutions' 88} 89b_basic_backticks_body() { 90 atf_check -s exit:0 -o match:'Result is true today' -e empty \ 91 ${TEST_SH} -c \ 92 'echo Result is `true && echo true || echo false` today' 93 94 atf_check -s exit:0 -o match:'Result is false today' -e empty \ 95 ${TEST_SH} -c \ 96 'echo Result is `false && echo true || echo false` today' 97 98 atf_check -s exit:0 -o match:'aaabbbccc' -e empty \ 99 ${TEST_SH} -c 'echo aaa` echo bbb `ccc' 100 atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \ 101 ${TEST_SH} -c 'echo aaa` echo bbb ccc `ddd' 102 atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \ 103 ${TEST_SH} -c 'echo aaa` echo bbb; echo ccc `ddd' 104 atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \ 105 ${TEST_SH} -c 'echo "aaa` echo bbb; echo ccc `ddd"' 106 107 atf_check -s exit:0 -o inline:'some string\n' -e empty \ 108 ${TEST_SH} -c 'X=` echo some string `; echo "$X"' 109 atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \ 110 ${TEST_SH} -c 'X=` echo "weird; string *" `; echo "$X"' 111 112 rm -f * 2>/dev/null || : 113 for f in file-1 file-2 114 do 115 cp /dev/null "$f" 116 done 117 118 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 119 ${TEST_SH} -c 'echo Found ` echo * `' 120 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 121 ${TEST_SH} -c 'echo Found "` echo * `"' 122 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 123 ${TEST_SH} -c 'echo Found `'" echo '*' "'`' 124 atf_check -s exit:0 -o match:'Found \*' -e empty \ 125 ${TEST_SH} -c 'echo Found "`'" echo '*' "'`"' 126 atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 127 ${TEST_SH} -c 'echo Found `'" echo \\* "'`' 128 atf_check -s exit:0 -o match:'Found \*' -e empty \ 129 ${TEST_SH} -c 'echo Found "`'" echo \\* "'`"' 130} 131 132atf_test_case c_nested_cmdsub 133c_nested_cmdsub_head() { 134 atf_set "descr" "Test that cmd substitutions can be nested" 135} 136c_nested_cmdsub_body() { 137 atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 138 ${TEST_SH} -c 'echo __$( echo foo$(echo bar)bletch )__' 139 atf_check -s exit:0 -o match:'_abcde_' -e empty \ 140 ${TEST_SH} -c 'echo _$(echo a$(echo $(echo b)c$(echo d))e )_' 141 atf_check -s exit:0 -o match:'123454321' -e empty \ 142 ${TEST_SH} -c 'echo 1$(echo 2$(echo 3$(echo 4$(echo 5)4)3)2)1' 143} 144 145atf_test_case d_nested_backticks 146d_nested_backticks_head() { 147 atf_set "descr" "Tests that old style backtick cmd subs can be nested" 148} 149d_nested_backticks_body() { 150 atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 151 ${TEST_SH} -c 'echo __` echo foo\`echo bar\`bletch `__' 152 atf_check -s exit:0 -o match:'_abcde_' -e empty \ 153 ${TEST_SH} -c \ 154 'echo _`echo a\`echo \\\`echo b\\\`c\\\`echo d\\\`\`e `_' 155 atf_check -s exit:0 -o match:'123454321' -e empty \ 156 ${TEST_SH} -c \ 157 'echo 1`echo 2\`echo 3\\\`echo 4\\\\\\\`echo 5\\\\\\\`4\\\`3\`2`1' 158} 159 160atf_test_case e_perverse_mixing 161e_perverse_mixing_head() { 162 atf_set "descr" \ 163 "Checks various mixed new and old style cmd substitutions" 164} 165e_perverse_mixing_body() { 166 atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 167 ${TEST_SH} -c 'echo __$( echo foo`echo bar`bletch )__' 168 atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 169 ${TEST_SH} -c 'echo __` echo foo$(echo bar)bletch `__' 170 atf_check -s exit:0 -o match:'_abcde_' -e empty \ 171 ${TEST_SH} -c 'echo _$(echo a`echo $(echo b)c$(echo d)`e )_' 172 atf_check -s exit:0 -o match:'_abcde_' -e empty \ 173 ${TEST_SH} -c 'echo _`echo a$(echo \`echo b\`c\`echo d\`)e `_' 174 atf_check -s exit:0 -o match:'12345654321' -e empty \ 175 ${TEST_SH} -c \ 176 'echo 1`echo 2$(echo 3\`echo 4\\\`echo 5$(echo 6)5\\\`4\`3)2`1' 177} 178 179atf_test_case f_redirect_in_cmdsub 180f_redirect_in_cmdsub_head() { 181 atf_set "descr" "Checks that redirects work in command substitutions" 182} 183f_redirect_in_cmdsub_body() { 184 atf_require_prog cat 185 atf_require_prog rm 186 187 rm -f file 2>/dev/null || : 188 atf_check -s exit:0 -o match:'_aa_' -e empty \ 189 ${TEST_SH} -c 'echo _$( echo a$( echo b > file )a)_' 190 atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file' 191 atf_check -s exit:0 -o match:'_aba_' -e empty \ 192 ${TEST_SH} -c 'echo _$( echo a$( cat < file )a)_' 193 atf_check -s exit:0 -o match:'_aa_' -e empty \ 194 ${TEST_SH} -c 'echo _$( echo a$( echo d >> file )a)_' 195 atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file' 196 atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \ 197 ${TEST_SH} -c 'echo _$( echo a$( echo not error >&2 )a)_' 198} 199 200atf_test_case g_redirect_in_backticks 201g_redirect_in_backticks_head() { 202 atf_set "descr" "Checks that redirects work in old style cmd sub" 203} 204g_redirect_in_backticks_body() { 205 atf_require_prog cat 206 atf_require_prog rm 207 208 rm -f file 2>/dev/null || : 209 atf_check -s exit:0 -o match:'_aa_' -e empty \ 210 ${TEST_SH} -c 'echo _` echo a\` echo b > file \`a`_' 211 atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file' 212 atf_check -s exit:0 -o match:'_aba_' -e empty \ 213 ${TEST_SH} -c 'echo _` echo a\` cat < file \`a`_' 214 atf_check -s exit:0 -o match:'_aa_' -e empty \ 215 ${TEST_SH} -c 'echo _` echo a\` echo d >> file \`a`_' 216 atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file' 217 atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \ 218 ${TEST_SH} -c 'echo _` echo a\` echo not error >&2 \`a`_' 219} 220 221atf_test_case h_vars_in_cmdsub 222h_vars_in_cmdsub_head() { 223 atf_set "descr" "Check that variables work in command substitutions" 224} 225h_vars_in_cmdsub_body() { 226 atf_check -s exit:0 -o match:'__abc__' -e empty \ 227 ${TEST_SH} -c 'X=abc; echo __$( echo ${X} )__' 228 atf_check -s exit:0 -o match:'__abc__' -e empty \ 229 ${TEST_SH} -c 'X=abc; echo __$( echo "${X}" )__' 230 atf_check -s exit:0 -o match:'__abc__' -e empty \ 231 ${TEST_SH} -c 'X=abc; echo "__$( echo ${X} )__"' 232 atf_check -s exit:0 -o match:'__abc__' -e empty \ 233 ${TEST_SH} -c 'X=abc; echo "__$( echo "${X}" )__"' 234 235 atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \ 236 ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done' 237 238 atf_check -s exit:0 -o match:'__acd__' -e empty \ 239 ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"' 240 atf_check -s exit:0 -o match:'__abcd__' -e empty \ 241 ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"' 242 atf_check -s exit:0 -o match:'__XYX__' -e empty \ 243 ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"' 244 atf_check -s exit:0 -o match:'__def__' -e empty \ 245 ${TEST_SH} -c 'X=abc; echo "__$(X=def; echo "${X}" )__"' 246 atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \ 247 ${TEST_SH} -c 'X=abc; echo "$X$(X=def; echo ${X} )"; echo $X' 248} 249 250atf_test_case i_vars_in_backticks 251i_vars_in_backticks_head() { 252 atf_set "descr" "Checks that variables work in old style cmd sub" 253} 254i_vars_in_backticks_body() { 255 atf_check -s exit:0 -o match:'__abc__' -e empty \ 256 ${TEST_SH} -c 'X=abc; echo __` echo ${X} `__' 257 atf_check -s exit:0 -o match:'__abc__' -e empty \ 258 ${TEST_SH} -c 'X=abc; echo __` echo "${X}" `__' 259 atf_check -s exit:0 -o match:'__abc__' -e empty \ 260 ${TEST_SH} -c 'X=abc; echo "__` echo ${X} `__"' 261 atf_check -s exit:0 -o match:'__abc__' -e empty \ 262 ${TEST_SH} -c 'X=abc; echo "__` echo \"${X}\" `__"' 263 264 atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \ 265 ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done' 266 267 atf_check -s exit:0 -o match:'__acd__' -e empty \ 268 ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"' 269 atf_check -s exit:0 -o match:'__abcd__' -e empty \ 270 ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"' 271 atf_check -s exit:0 -o match:'__XYX__' -e empty \ 272 ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"' 273 atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \ 274 ${TEST_SH} -c 'X=abc; echo "$X`X=def; echo \"${X}\" `";echo $X' 275 276 # The following is nonsense, so is not included ... 277 # atf_check -s exit:0 -o match:'__abc__' -e empty \ 278 # oV cV oV cV 279 # ${TEST_SH} -c 'X=abc; echo "__`X=def echo "${X}" `__"' 280 # `start in " ^ " ends, ` not yet 281} 282 283atf_test_case j_cmdsub_in_varexpand 284j_cmdsub_in_varexpand_head() { 285 atf_set "descr" "Checks that command sub can be used in var expansion" 286} 287j_cmdsub_in_varexpand_body() { 288 atf_check -s exit:0 -o match:'foo' -e empty \ 289 ${TEST_SH} -c 'X=set; echo ${X+$(echo foo)}' 290 atf_check -s exit:0 -o match:'set' -e empty \ 291 ${TEST_SH} -c 'X=set; echo ${X-$(echo foo)}' 292 rm -f bar 2>/dev/null || : 293 atf_check -s exit:0 -o match:'set' -e empty \ 294 ${TEST_SH} -c 'X=set; echo ${X-$(echo foo > bar)}' 295 test -f bar && atf_fail "bar should not exist, but does" 296 atf_check -s exit:0 -o inline:'\n' -e empty \ 297 ${TEST_SH} -c 'X=set; echo ${X+$(echo foo > bar)}' 298 test -f bar || atf_fail "bar should exist, but does not" 299} 300 301atf_test_case k_backticks_in_varexpand 302k_backticks_in_varexpand_head() { 303 atf_set "descr" "Checks that old style cmd sub works in var expansion" 304} 305k_backticks_in_varexpand_body() { 306 atf_check -s exit:0 -o match:'foo' -e empty \ 307 ${TEST_SH} -c 'X=set; echo ${X+`echo foo`}' 308 atf_check -s exit:0 -o match:'set' -e empty \ 309 ${TEST_SH} -c 'X=set; echo ${X-`echo foo`}' 310 rm -f bar 2>/dev/null || : 311 atf_check -s exit:0 -o match:'set' -e empty \ 312 ${TEST_SH} -c 'X=set; echo ${X-`echo foo > bar`}' 313 test -f bar && atf_fail "bar should not exist, but does" 314 atf_check -s exit:0 -o inline:'\n' -e empty \ 315 ${TEST_SH} -c 'X=set; echo ${X+`echo foo > bar`}' 316 test -f bar || atf_fail "bar should exist, but does not" 317} 318 319atf_test_case l_arithmetic_in_cmdsub 320l_arithmetic_in_cmdsub_head() { 321 atf_set "descr" "Checks that arithmetic works in cmd substitutions" 322} 323l_arithmetic_in_cmdsub_body() { 324 atf_check -s exit:0 -o inline:'1 + 1 = 2\n' -e empty \ 325 ${TEST_SH} -c 'echo 1 + 1 = $( echo $(( 1 + 1 )) )' 326 atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \ 327 ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = $( echo $(( X * Y )) )' 328 atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \ 329 ${TEST_SH} -c 'X=2; Y=3; echo Y % X = $( echo $(( $Y % $X )) )' 330} 331 332atf_test_case m_arithmetic_in_backticks 333m_arithmetic_in_backticks_head() { 334 atf_set "descr" "Checks that arithmetic works in old style cmd sub" 335} 336m_arithmetic_in_backticks_body() { 337 atf_check -s exit:0 -o inline:'2 + 3 = 5\n' -e empty \ 338 ${TEST_SH} -c 'echo 2 + 3 = ` echo $(( 2 + 3 )) `' 339 atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \ 340 ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = ` echo $(( X * Y )) `' 341 atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \ 342 ${TEST_SH} -c 'X=2; Y=3; echo Y % X = ` echo $(( $Y % $X )) `' 343} 344 345atf_test_case n_cmdsub_in_arithmetic 346n_cmdsub_in_arithmetic_head() { 347 atf_set "descr" "Tests uses of command substitutions in arithmetic" 348} 349n_cmdsub_in_arithmetic_body() { 350 atf_check -s exit:0 -o inline:'7\n' -e empty \ 351 ${TEST_SH} -c 'echo $(( $( echo 3 ) $( echo + ) $( echo 4 ) ))' 352 atf_check -s exit:0 -o inline:'11\n7\n18\n4\n1\n' -e empty \ 353 ${TEST_SH} -c \ 354 'for op in + - \* / % 355 do 356 echo $(( $( echo 9 ) $( echo "${op}" ) $( echo 2 ) )) 357 done' 358} 359 360atf_test_case o_backticks_in_arithmetic 361o_backticks_in_arithmetic_head() { 362 atf_set "descr" "Tests old style cmd sub used in arithmetic" 363} 364o_backticks_in_arithmetic_body() { 365 atf_check -s exit:0 -o inline:'33\n' -e empty \ 366 ${TEST_SH} -c 'echo $(( `echo 77` `echo -` `echo 44`))' 367 atf_check -s exit:0 -o inline:'14\n8\n33\n3\n2\n' -e empty \ 368 ${TEST_SH} -c \ 369 'for op in + - \* / % 370 do 371 echo $((`echo 11``echo "${op}"``echo 3`)) 372 done' 373} 374 375atf_test_case p_cmdsub_in_heredoc 376p_cmdsub_in_heredoc_head() { 377 atf_set "descr" "Checks that cmdsubs work inside a here document" 378} 379p_cmdsub_in_heredoc_body() { 380 atf_require_prog cat 381 382 atf_check -s exit:0 -o inline:'line 1+1\nline 2\nline 3\n' -e empty \ 383 ${TEST_SH} -c \ 384 'cat <<- EOF 385 $( echo line 1 )$( echo +1 ) 386 $( echo line 2;echo line 3 ) 387 EOF' 388} 389 390atf_test_case q_backticks_in_heredoc 391q_backticks_in_heredoc_head() { 392 atf_set "descr" "Checks that old style cmdsubs work in here docs" 393} 394q_backticks_in_heredoc_body() { 395 atf_require_prog cat 396 397 atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ 398 ${TEST_SH} -c \ 399 'cat <<- EOF 400 `echo Mary ` `echo had a ` 401 ` echo little; echo lamb ` 402 EOF' 403} 404 405atf_test_case r_heredoc_in_cmdsub 406r_heredoc_in_cmdsub_head() { 407 atf_set "descr" "Checks that here docs work inside cmd subs" 408} 409r_heredoc_in_cmdsub_body() { 410 atf_require_prog cat 411 412 atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ 413 ${TEST_SH} -c 'echo "$( cat <<- \EOF 414 Mary had a 415 little 416 lamb 417 EOF 418 )"' 419 420 atf_check -s exit:0 -e empty \ 421 -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \ 422 ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF 423 Mary had ${N} 424 little 425 lamb$( [ $N -gt 1 ] && echo s ) 426 EOF 427 )"; done' 428 429 430 atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \ 431 ${TEST_SH} -c 'echo "$( cat <<- EOF 432 A Calculation: 433 2 * 7 = $(( 2 * 7 )) 434 EOF 435 )"' 436} 437 438atf_test_case s_heredoc_in_backticks 439s_heredoc_in_backticks_head() { 440 atf_set "descr" "Checks that here docs work inside old style cmd subs" 441} 442s_heredoc_in_backticks_body() { 443 atf_require_prog cat 444 445 atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \ 446 ${TEST_SH} -c 'echo ` cat <<- \EOF 447 Mary had a 448 little 449 lamb 450 EOF 451 `' 452 453 atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \ 454 ${TEST_SH} -c 'echo "` cat <<- EOF 455 A Calculation: 456 17 / 3 = $(( 17 / 3 )) 457 EOF 458 `"' 459} 460 461atf_test_case t_nested_cmdsubs_in_heredoc 462t_nested_cmdsubs_in_heredoc_head() { 463 atf_set "descr" "Checks nested command substitutions in here docs" 464} 465t_nested_cmdsubs_in_heredoc_body() { 466 atf_require_prog cat 467 atf_require_prog rm 468 469 rm -f * 2>/dev/null || : 470 echo "Hello" > File 471 472 atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ 473 ${TEST_SH} -c 'cat <<- EOF 474 $(cat File) U 475 $( V=$(cat File); echo "${V%lo}p" ) me! 476 EOF' 477 478 rm -f * 2>/dev/null || : 479 echo V>V ; echo A>A; echo R>R 480 echo Value>VAR 481 482 atf_check -s exit:0 -o inline:'$2.50\n' -e empty \ 483 ${TEST_SH} -c 'cat <<- EOF 484 $(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2}))) 485 EOF' 486} 487 488atf_test_case u_nested_backticks_in_heredoc 489u_nested_backticks_in_heredoc_head() { 490 atf_set "descr" "Checks nested old style cmd subs in here docs" 491} 492u_nested_backticks_in_heredoc_body() { 493 atf_require_prog cat 494 atf_require_prog rm 495 496 rm -f * 2>/dev/null || : 497 echo "Hello" > File 498 499 atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ 500 ${TEST_SH} -c 'cat <<- EOF 501 `cat File` U 502 `V=\`cat File\`; echo "${V%lo}p" ` me! 503 EOF' 504 505 rm -f * 2>/dev/null || : 506 echo V>V ; echo A>A; echo R>R 507 echo Value>VAR 508 509 atf_check -s exit:0 -o inline:'$5.20\n' -e empty \ 510 ${TEST_SH} -c 'cat <<- EOF 511 `Value='\''$5.20'\'';eval echo \`eval \\\`cat V\\\`\\\`cat A\\\`\\\`cat R\\\`=\\\'\''\\\$\\\`cat \\\\\\\`cat V\\\\\\\`\\\\\\\`cat A\\\\\\\`\\\\\\\`cat R\\\\\\\`\\\`\\\'\''; eval echo \\\$\\\`set -- *;echo \\\\\${3}\\\\\${1}\\\\\${2}\\\`\`` 512 EOF' 513} 514 515atf_test_case v_cmdsub_paren_tests 516v_cmdsub__paren_tests_head() { 517 atf_set "descr" "tests with cmdsubs containing embedded ')'" 518} 519v_cmdsub_paren_tests_body() { 520 521 # Tests from: 522 # http://www.in-ulm.de/~mascheck/various/cmd-subst/ 523 # (slightly modified.) 524 525 atf_check -s exit:0 -o inline:'A.1\n' -e empty ${TEST_SH} -c \ 526 'echo $( 527 case x in x) echo A.1;; esac 528 )' 529 530 atf_check -s exit:0 -o inline:'A.2\n' -e empty ${TEST_SH} -c \ 531 'echo $( 532 case x in x) echo A.2;; esac # comment 533 )' 534 535 atf_check -s exit:0 -o inline:'A.3\n' -e empty ${TEST_SH} -c \ 536 'echo $( 537 case x in (x) echo A.3;; esac 538 )' 539 540 atf_check -s exit:0 -o inline:'A.4\n' -e empty ${TEST_SH} -c \ 541 'echo $( 542 case x in (x) echo A.4;; esac # comment 543 )' 544 545 atf_check -s exit:0 -o inline:'A.5\n' -e empty ${TEST_SH} -c \ 546 'echo $( 547 case x in (x) echo A.5 548 esac 549 )' 550 551 atf_check -s exit:0 -o inline:'B: quoted )\n' -e empty ${TEST_SH} -c \ 552 'echo $( 553 echo '\''B: quoted )'\'' 554 )' 555 556 atf_check -s exit:0 -o inline:'C: comment then closing paren\n' \ 557 -e empty ${TEST_SH} -c \ 558 'echo $( 559 echo C: comment then closing paren # ) 560 )' 561 562 atf_check -s exit:0 -o inline:'D.1: here-doc with )\n' \ 563 -e empty ${TEST_SH} -c \ 564 'echo $( 565 cat <<-\eof 566 D.1: here-doc with ) 567 eof 568 )' 569 570 # D.2 is a bogus test. 571 572 atf_check -s exit:0 -o inline:'D.3: here-doc with \()\n' \ 573 -e empty ${TEST_SH} -c \ 574 'echo $( 575 cat <<-\eof 576 D.3: here-doc with \() 577 eof 578 )' 579 580 atf_check -s exit:0 -e empty \ 581 -o inline:'E: here-doc terminated with a parenthesis ("academic")\n' \ 582 ${TEST_SH} -c \ 583 'echo $( 584 cat <<-\) 585 E: here-doc terminated with a parenthesis ("academic") 586 ) 587 )' 588 589 atf_check -s exit:0 -e empty \ 590-o inline:'F.1: here-doc embed with unbal single, back- or doublequote '\''\n' \ 591 ${TEST_SH} -c \ 592 'echo $( 593 cat <<-"eof" 594 F.1: here-doc embed with unbal single, back- or doublequote '\'' 595 eof 596 )' 597 atf_check -s exit:0 -e empty \ 598 -o inline:'F.2: here-doc embed with unbal single, back- or doublequote "\n' \ 599 ${TEST_SH} -c \ 600 'echo $( 601 cat <<-"eof" 602 F.2: here-doc embed with unbal single, back- or doublequote " 603 eof 604 )' 605 atf_check -s exit:0 -e empty \ 606 -o inline:'F.3: here-doc embed with unbal single, back- or doublequote `\n' \ 607 ${TEST_SH} -c \ 608 'echo $( 609 cat <<-"eof" 610 F.3: here-doc embed with unbal single, back- or doublequote ` 611 eof 612 )' 613 614 atf_check -s exit:0 -e empty -o inline:'G: backslash at end of line\n' \ 615 ${TEST_SH} -c \ 616 'echo $( 617 echo G: backslash at end of line # \ 618 )' 619 620 atf_check -s exit:0 -e empty \ 621 -o inline:'H: empty command-substitution\n' \ 622 ${TEST_SH} -c 'echo H: empty command-substitution $( )' 623} 624 625atf_test_case w_heredoc_outside_cmdsub 626w_heredoc_outside_cmdsub_head() { 627 atf_set "descr" "Checks that here docs work inside cmd subs" 628} 629w_heredoc_outside_cmdsub_body() { 630 atf_require_prog cat 631 632 atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ 633 ${TEST_SH} -c 'echo "$( cat <<- \EOF )" 634 Mary had a 635 little 636 lamb 637 EOF 638 ' 639 640 atf_check -s exit:0 -e empty \ 641 -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \ 642 ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF )" 643 Mary had ${N} 644 little 645 lamb$( [ $N -gt 1 ] && echo s ) 646 EOF 647 done' 648 649 650 atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \ 651 ${TEST_SH} -c 'echo "$( cat <<- EOF)" 652 A Calculation: 653 2 * 7 = $(( 2 * 7 )) 654 EOF 655 ' 656} 657 658atf_test_case x_heredoc_outside_backticks 659x_heredoc_outside_backticks_head() { 660 atf_set "descr" "Checks that here docs work inside old style cmd subs" 661} 662x_heredoc_outside_backticks_body() { 663 atf_require_prog cat 664 665 atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \ 666 ${TEST_SH} -c 'echo ` cat <<- \EOF ` 667 Mary had a 668 little 669 lamb 670 EOF 671 ' 672 673 atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \ 674 ${TEST_SH} -c 'echo "` cat <<- EOF `" 675 A Calculation: 676 17 / 3 = $(( 17 / 3 )) 677 EOF 678 ' 679} 680 681atf_test_case t_nested_cmdsubs_in_heredoc 682t_nested_cmdsubs_in_heredoc_head() { 683 atf_set "descr" "Checks nested command substitutions in here docs" 684} 685t_nested_cmdsubs_in_heredoc_body() { 686 atf_require_prog cat 687 atf_require_prog rm 688 689 rm -f * 2>/dev/null || : 690 echo "Hello" > File 691 692 atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ 693 ${TEST_SH} -c 'cat <<- EOF 694 $(cat File) U 695 $( V=$(cat File); echo "${V%lo}p" ) me! 696 EOF' 697 698 rm -f * 2>/dev/null || : 699 echo V>V ; echo A>A; echo R>R 700 echo Value>VAR 701 702 atf_check -s exit:0 -o inline:'$2.50\n' -e empty \ 703 ${TEST_SH} -c 'cat <<- EOF 704 $(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2}))) 705 EOF' 706} 707 708atf_test_case z_absurd_heredoc_cmdsub_combos 709z_absurd_heredoc_cmdsub_combos_head() { 710 atf_set "descr" "perverse and unusual cmd substitutions & more" 711} 712z_absurd_heredoc_cmdsub_combos_body() { 713 714 echo "Help!" > help 715 716 # This version works in NetBSD (& FreeBSD)'s sh (and most others) 717 atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c ' 718 cat <<- EOF 719 $( 720 cat <<- STOP 721 $( 722 cat `echo help` 723 ) 724 STOP 725 ) 726 $( 727 cat <<- END 4<<-TRASH 728 Me $(( 1 + 1 )) 729 END 730 This is unused noise! 731 TRASH 732 ) 733 EOF 734 ' 735 736 # atf_expect_fail "PR bin/50993 - heredoc parsing done incorrectly" 737 atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c ' 738 cat <<- EOF 739 $( 740 cat << STOP 741 $( 742 cat `echo help` 743 ) 744 STOP 745 ) 746 $( 747 cat <<- END 4<<TRASH 748 Me $(( 1 + 1 )) 749 END 750 This is unused noise! 751 TRASH 752 ) 753 EOF 754 ' 755} 756 757atf_init_test_cases() { 758 atf_add_test_case a_basic_cmdsub 759 atf_add_test_case b_basic_backticks 760 atf_add_test_case c_nested_cmdsub 761 atf_add_test_case d_nested_backticks 762 atf_add_test_case e_perverse_mixing 763 atf_add_test_case f_redirect_in_cmdsub 764 atf_add_test_case g_redirect_in_backticks 765 atf_add_test_case h_vars_in_cmdsub 766 atf_add_test_case i_vars_in_backticks 767 atf_add_test_case j_cmdsub_in_varexpand 768 atf_add_test_case k_backticks_in_varexpand 769 atf_add_test_case l_arithmetic_in_cmdsub 770 atf_add_test_case m_arithmetic_in_backticks 771 atf_add_test_case n_cmdsub_in_arithmetic 772 atf_add_test_case o_backticks_in_arithmetic 773 atf_add_test_case p_cmdsub_in_heredoc 774 atf_add_test_case q_backticks_in_heredoc 775 atf_add_test_case r_heredoc_in_cmdsub 776 atf_add_test_case s_heredoc_in_backticks 777 atf_add_test_case t_nested_cmdsubs_in_heredoc 778 atf_add_test_case u_nested_backticks_in_heredoc 779 atf_add_test_case v_cmdsub_paren_tests 780 atf_add_test_case w_heredoc_outside_cmdsub 781 atf_add_test_case x_heredoc_outside_backticks 782 atf_add_test_case z_absurd_heredoc_cmdsub_combos 783} 784