1303980Sngie# $NetBSD: t_cmdsub.sh,v 1.4 2016/04/04 12:40:13 christos Exp $ 2303980Sngie# 3303980Sngie# Copyright (c) 2016 The NetBSD Foundation, Inc. 4303980Sngie# All rights reserved. 5303980Sngie# 6303980Sngie# Redistribution and use in source and binary forms, with or without 7303980Sngie# modification, are permitted provided that the following conditions 8303980Sngie# are met: 9303980Sngie# 1. Redistributions of source code must retain the above copyright 10303980Sngie# notice, this list of conditions and the following disclaimer. 11303980Sngie# 2. Redistributions in binary form must reproduce the above copyright 12303980Sngie# notice, this list of conditions and the following disclaimer in the 13303980Sngie# documentation and/or other materials provided with the distribution. 14303980Sngie# 15303980Sngie# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16303980Sngie# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17303980Sngie# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18303980Sngie# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19303980Sngie# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20303980Sngie# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21303980Sngie# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22303980Sngie# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23303980Sngie# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24303980Sngie# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25303980Sngie# POSSIBILITY OF SUCH DAMAGE. 26303980Sngie# 27303980Sngie# the implementation of "sh" to test 28303980Sngie: ${TEST_SH:="/bin/sh"} 29303980Sngie 30303980Sngie# 31303980Sngie# This file tests command substitutions ( `...` and $( ... ) ) 32303980Sngie# 33303980Sngie# CAUTION: 34303980Sngie# Be careful attempting running these tests outside the ATF environment 35303980Sngie# Some of the tests run "rm *" in the current directory to clean up 36303980Sngie# An ATF test directory should be empty already, outside ATF, anything 37303980Sngie 38303980Sngieatf_test_case a_basic_cmdsub 39303980Sngiea_basic_cmdsub_head() { 40303980Sngie atf_set "descr" 'Test operation of simple $( ) substitutions' 41303980Sngie} 42303980Sngiea_basic_cmdsub_body() { 43303980Sngie atf_check -s exit:0 -o match:'Result is true today' -e empty \ 44303980Sngie ${TEST_SH} -c \ 45303980Sngie 'echo Result is $( true && echo true || echo false ) today' 46303980Sngie 47303980Sngie atf_check -s exit:0 -o match:'Result is false today' -e empty \ 48303980Sngie ${TEST_SH} -c \ 49303980Sngie 'echo Result is $( false && echo true || echo false ) today' 50303980Sngie 51303980Sngie atf_check -s exit:0 -o match:'aaabbbccc' -e empty \ 52303980Sngie ${TEST_SH} -c 'echo aaa$( echo bbb )ccc' 53303980Sngie atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \ 54303980Sngie ${TEST_SH} -c 'echo aaa$( echo bbb ccc )ddd' 55303980Sngie atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \ 56303980Sngie ${TEST_SH} -c 'echo aaa$( echo bbb; echo ccc )ddd' 57303980Sngie atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \ 58303980Sngie ${TEST_SH} -c 'echo "aaa$( echo bbb; echo ccc )ddd"' 59303980Sngie 60303980Sngie atf_check -s exit:0 -o inline:'some string\n' -e empty \ 61303980Sngie ${TEST_SH} -c 'X=$( echo some string ); echo "$X"' 62303980Sngie atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \ 63303980Sngie ${TEST_SH} -c 'X=$( echo "weird; string *" ); echo "$X"' 64303980Sngie 65303980Sngie rm -f * 2>/dev/null || : 66303980Sngie for f in file-1 file-2 67303980Sngie do 68303980Sngie cp /dev/null "$f" 69303980Sngie done 70303980Sngie 71303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 72303980Sngie ${TEST_SH} -c 'echo Found $( echo * )' 73303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 74303980Sngie ${TEST_SH} -c 'echo Found "$( echo * )"' 75303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 76303980Sngie ${TEST_SH} -c 'echo Found $('" echo '*' )" 77303980Sngie atf_check -s exit:0 -o match:'Found \*' -e empty \ 78303980Sngie ${TEST_SH} -c 'echo Found "$('" echo '*' "')"' 79303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 80303980Sngie ${TEST_SH} -c 'echo Found $('" echo \\* )" 81303980Sngie atf_check -s exit:0 -o match:'Found \*' -e empty \ 82303980Sngie ${TEST_SH} -c 'echo Found "$('" echo \\* )"\" 83303980Sngie} 84303980Sngie 85303980Sngieatf_test_case b_basic_backticks 86303980Sngieb_basic_backticks_head() { 87303980Sngie atf_set "descr" 'Test operation of old style ` ` substitutions' 88303980Sngie} 89303980Sngieb_basic_backticks_body() { 90303980Sngie atf_check -s exit:0 -o match:'Result is true today' -e empty \ 91303980Sngie ${TEST_SH} -c \ 92303980Sngie 'echo Result is `true && echo true || echo false` today' 93303980Sngie 94303980Sngie atf_check -s exit:0 -o match:'Result is false today' -e empty \ 95303980Sngie ${TEST_SH} -c \ 96303980Sngie 'echo Result is `false && echo true || echo false` today' 97303980Sngie 98303980Sngie atf_check -s exit:0 -o match:'aaabbbccc' -e empty \ 99303980Sngie ${TEST_SH} -c 'echo aaa` echo bbb `ccc' 100303980Sngie atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \ 101303980Sngie ${TEST_SH} -c 'echo aaa` echo bbb ccc `ddd' 102303980Sngie atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \ 103303980Sngie ${TEST_SH} -c 'echo aaa` echo bbb; echo ccc `ddd' 104303980Sngie atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \ 105303980Sngie ${TEST_SH} -c 'echo "aaa` echo bbb; echo ccc `ddd"' 106303980Sngie 107303980Sngie atf_check -s exit:0 -o inline:'some string\n' -e empty \ 108303980Sngie ${TEST_SH} -c 'X=` echo some string `; echo "$X"' 109303980Sngie atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \ 110303980Sngie ${TEST_SH} -c 'X=` echo "weird; string *" `; echo "$X"' 111303980Sngie 112303980Sngie rm -f * 2>/dev/null || : 113303980Sngie for f in file-1 file-2 114303980Sngie do 115303980Sngie cp /dev/null "$f" 116303980Sngie done 117303980Sngie 118303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 119303980Sngie ${TEST_SH} -c 'echo Found ` echo * `' 120303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 121303980Sngie ${TEST_SH} -c 'echo Found "` echo * `"' 122303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 123303980Sngie ${TEST_SH} -c 'echo Found `'" echo '*' "'`' 124303980Sngie atf_check -s exit:0 -o match:'Found \*' -e empty \ 125303980Sngie ${TEST_SH} -c 'echo Found "`'" echo '*' "'`"' 126303980Sngie atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ 127303980Sngie ${TEST_SH} -c 'echo Found `'" echo \\* "'`' 128303980Sngie atf_check -s exit:0 -o match:'Found \*' -e empty \ 129303980Sngie ${TEST_SH} -c 'echo Found "`'" echo \\* "'`"' 130303980Sngie} 131303980Sngie 132303980Sngieatf_test_case c_nested_cmdsub 133303980Sngiec_nested_cmdsub_head() { 134303980Sngie atf_set "descr" "Test that cmd substitutions can be nested" 135303980Sngie} 136303980Sngiec_nested_cmdsub_body() { 137303980Sngie atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 138303980Sngie ${TEST_SH} -c 'echo __$( echo foo$(echo bar)bletch )__' 139303980Sngie atf_check -s exit:0 -o match:'_abcde_' -e empty \ 140303980Sngie ${TEST_SH} -c 'echo _$(echo a$(echo $(echo b)c$(echo d))e )_' 141303980Sngie atf_check -s exit:0 -o match:'123454321' -e empty \ 142303980Sngie ${TEST_SH} -c 'echo 1$(echo 2$(echo 3$(echo 4$(echo 5)4)3)2)1' 143303980Sngie} 144303980Sngie 145303980Sngieatf_test_case d_nested_backticks 146303980Sngied_nested_backticks_head() { 147303980Sngie atf_set "descr" "Tests that old style backtick cmd subs can be nested" 148303980Sngie} 149303980Sngied_nested_backticks_body() { 150303980Sngie atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 151303980Sngie ${TEST_SH} -c 'echo __` echo foo\`echo bar\`bletch `__' 152303980Sngie atf_check -s exit:0 -o match:'_abcde_' -e empty \ 153303980Sngie ${TEST_SH} -c \ 154303980Sngie 'echo _`echo a\`echo \\\`echo b\\\`c\\\`echo d\\\`\`e `_' 155303980Sngie atf_check -s exit:0 -o match:'123454321' -e empty \ 156303980Sngie ${TEST_SH} -c \ 157303980Sngie 'echo 1`echo 2\`echo 3\\\`echo 4\\\\\\\`echo 5\\\\\\\`4\\\`3\`2`1' 158303980Sngie} 159303980Sngie 160303980Sngieatf_test_case e_perverse_mixing 161303980Sngiee_perverse_mixing_head() { 162303980Sngie atf_set "descr" \ 163303980Sngie "Checks various mixed new and old style cmd substitutions" 164303980Sngie} 165303980Sngiee_perverse_mixing_body() { 166303980Sngie atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 167303980Sngie ${TEST_SH} -c 'echo __$( echo foo`echo bar`bletch )__' 168303980Sngie atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ 169303980Sngie ${TEST_SH} -c 'echo __` echo foo$(echo bar)bletch `__' 170303980Sngie atf_check -s exit:0 -o match:'_abcde_' -e empty \ 171303980Sngie ${TEST_SH} -c 'echo _$(echo a`echo $(echo b)c$(echo d)`e )_' 172303980Sngie atf_check -s exit:0 -o match:'_abcde_' -e empty \ 173303980Sngie ${TEST_SH} -c 'echo _`echo a$(echo \`echo b\`c\`echo d\`)e `_' 174303980Sngie atf_check -s exit:0 -o match:'12345654321' -e empty \ 175303980Sngie ${TEST_SH} -c \ 176303980Sngie 'echo 1`echo 2$(echo 3\`echo 4\\\`echo 5$(echo 6)5\\\`4\`3)2`1' 177303980Sngie} 178303980Sngie 179303980Sngieatf_test_case f_redirect_in_cmdsub 180303980Sngief_redirect_in_cmdsub_head() { 181303980Sngie atf_set "descr" "Checks that redirects work in command substitutions" 182303980Sngie} 183303980Sngief_redirect_in_cmdsub_body() { 184303980Sngie atf_require_prog cat 185303980Sngie atf_require_prog rm 186303980Sngie 187303980Sngie rm -f file 2>/dev/null || : 188303980Sngie atf_check -s exit:0 -o match:'_aa_' -e empty \ 189303980Sngie ${TEST_SH} -c 'echo _$( echo a$( echo b > file )a)_' 190303980Sngie atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file' 191303980Sngie atf_check -s exit:0 -o match:'_aba_' -e empty \ 192303980Sngie ${TEST_SH} -c 'echo _$( echo a$( cat < file )a)_' 193303980Sngie atf_check -s exit:0 -o match:'_aa_' -e empty \ 194303980Sngie ${TEST_SH} -c 'echo _$( echo a$( echo d >> file )a)_' 195303980Sngie atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file' 196303980Sngie atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \ 197303980Sngie ${TEST_SH} -c 'echo _$( echo a$( echo not error >&2 )a)_' 198303980Sngie} 199303980Sngie 200303980Sngieatf_test_case g_redirect_in_backticks 201303980Sngieg_redirect_in_backticks_head() { 202303980Sngie atf_set "descr" "Checks that redirects work in old style cmd sub" 203303980Sngie} 204303980Sngieg_redirect_in_backticks_body() { 205303980Sngie atf_require_prog cat 206303980Sngie atf_require_prog rm 207303980Sngie 208303980Sngie rm -f file 2>/dev/null || : 209303980Sngie atf_check -s exit:0 -o match:'_aa_' -e empty \ 210303980Sngie ${TEST_SH} -c 'echo _` echo a\` echo b > file \`a`_' 211303980Sngie atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file' 212303980Sngie atf_check -s exit:0 -o match:'_aba_' -e empty \ 213303980Sngie ${TEST_SH} -c 'echo _` echo a\` cat < file \`a`_' 214303980Sngie atf_check -s exit:0 -o match:'_aa_' -e empty \ 215303980Sngie ${TEST_SH} -c 'echo _` echo a\` echo d >> file \`a`_' 216303980Sngie atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file' 217303980Sngie atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \ 218303980Sngie ${TEST_SH} -c 'echo _` echo a\` echo not error >&2 \`a`_' 219303980Sngie} 220303980Sngie 221303980Sngieatf_test_case h_vars_in_cmdsub 222303980Sngieh_vars_in_cmdsub_head() { 223303980Sngie atf_set "descr" "Check that variables work in command substitutions" 224303980Sngie} 225303980Sngieh_vars_in_cmdsub_body() { 226303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 227303980Sngie ${TEST_SH} -c 'X=abc; echo __$( echo ${X} )__' 228303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 229303980Sngie ${TEST_SH} -c 'X=abc; echo __$( echo "${X}" )__' 230303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 231303980Sngie ${TEST_SH} -c 'X=abc; echo "__$( echo ${X} )__"' 232303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 233303980Sngie ${TEST_SH} -c 'X=abc; echo "__$( echo "${X}" )__"' 234303980Sngie 235303980Sngie atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \ 236303980Sngie ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done' 237303980Sngie 238303980Sngie atf_check -s exit:0 -o match:'__acd__' -e empty \ 239303980Sngie ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"' 240303980Sngie atf_check -s exit:0 -o match:'__abcd__' -e empty \ 241303980Sngie ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"' 242303980Sngie atf_check -s exit:0 -o match:'__XYX__' -e empty \ 243303980Sngie ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"' 244303980Sngie atf_check -s exit:0 -o match:'__def__' -e empty \ 245303980Sngie ${TEST_SH} -c 'X=abc; echo "__$(X=def; echo "${X}" )__"' 246303980Sngie atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \ 247303980Sngie ${TEST_SH} -c 'X=abc; echo "$X$(X=def; echo ${X} )"; echo $X' 248303980Sngie} 249303980Sngie 250303980Sngieatf_test_case i_vars_in_backticks 251303980Sngiei_vars_in_backticks_head() { 252303980Sngie atf_set "descr" "Checks that variables work in old style cmd sub" 253303980Sngie} 254303980Sngiei_vars_in_backticks_body() { 255303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 256303980Sngie ${TEST_SH} -c 'X=abc; echo __` echo ${X} `__' 257303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 258303980Sngie ${TEST_SH} -c 'X=abc; echo __` echo "${X}" `__' 259303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 260303980Sngie ${TEST_SH} -c 'X=abc; echo "__` echo ${X} `__"' 261303980Sngie atf_check -s exit:0 -o match:'__abc__' -e empty \ 262303980Sngie ${TEST_SH} -c 'X=abc; echo "__` echo \"${X}\" `__"' 263303980Sngie 264303980Sngie atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \ 265303980Sngie ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done' 266303980Sngie 267303980Sngie atf_check -s exit:0 -o match:'__acd__' -e empty \ 268303980Sngie ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"' 269303980Sngie atf_check -s exit:0 -o match:'__abcd__' -e empty \ 270303980Sngie ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"' 271303980Sngie atf_check -s exit:0 -o match:'__XYX__' -e empty \ 272303980Sngie ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"' 273303980Sngie atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \ 274303980Sngie ${TEST_SH} -c 'X=abc; echo "$X`X=def; echo \"${X}\" `";echo $X' 275303980Sngie 276303980Sngie # The following is nonsense, so is not included ... 277303980Sngie # atf_check -s exit:0 -o match:'__abc__' -e empty \ 278303980Sngie # oV cV oV cV 279303980Sngie # ${TEST_SH} -c 'X=abc; echo "__`X=def echo "${X}" `__"' 280303980Sngie # `start in " ^ " ends, ` not yet 281303980Sngie} 282303980Sngie 283303980Sngieatf_test_case j_cmdsub_in_varexpand 284303980Sngiej_cmdsub_in_varexpand_head() { 285303980Sngie atf_set "descr" "Checks that command sub can be used in var expansion" 286303980Sngie} 287303980Sngiej_cmdsub_in_varexpand_body() { 288303980Sngie atf_check -s exit:0 -o match:'foo' -e empty \ 289303980Sngie ${TEST_SH} -c 'X=set; echo ${X+$(echo foo)}' 290303980Sngie atf_check -s exit:0 -o match:'set' -e empty \ 291303980Sngie ${TEST_SH} -c 'X=set; echo ${X-$(echo foo)}' 292303980Sngie rm -f bar 2>/dev/null || : 293303980Sngie atf_check -s exit:0 -o match:'set' -e empty \ 294303980Sngie ${TEST_SH} -c 'X=set; echo ${X-$(echo foo > bar)}' 295303980Sngie test -f bar && atf_fail "bar should not exist, but does" 296303980Sngie atf_check -s exit:0 -o inline:'\n' -e empty \ 297303980Sngie ${TEST_SH} -c 'X=set; echo ${X+$(echo foo > bar)}' 298303980Sngie test -f bar || atf_fail "bar should exist, but does not" 299303980Sngie} 300303980Sngie 301303980Sngieatf_test_case k_backticks_in_varexpand 302303980Sngiek_backticks_in_varexpand_head() { 303303980Sngie atf_set "descr" "Checks that old style cmd sub works in var expansion" 304303980Sngie} 305303980Sngiek_backticks_in_varexpand_body() { 306303980Sngie atf_check -s exit:0 -o match:'foo' -e empty \ 307303980Sngie ${TEST_SH} -c 'X=set; echo ${X+`echo foo`}' 308303980Sngie atf_check -s exit:0 -o match:'set' -e empty \ 309303980Sngie ${TEST_SH} -c 'X=set; echo ${X-`echo foo`}' 310303980Sngie rm -f bar 2>/dev/null || : 311303980Sngie atf_check -s exit:0 -o match:'set' -e empty \ 312303980Sngie ${TEST_SH} -c 'X=set; echo ${X-`echo foo > bar`}' 313303980Sngie test -f bar && atf_fail "bar should not exist, but does" 314303980Sngie atf_check -s exit:0 -o inline:'\n' -e empty \ 315303980Sngie ${TEST_SH} -c 'X=set; echo ${X+`echo foo > bar`}' 316303980Sngie test -f bar || atf_fail "bar should exist, but does not" 317303980Sngie} 318303980Sngie 319303980Sngieatf_test_case l_arithmetic_in_cmdsub 320303980Sngiel_arithmetic_in_cmdsub_head() { 321303980Sngie atf_set "descr" "Checks that arithmetic works in cmd substitutions" 322303980Sngie} 323303980Sngiel_arithmetic_in_cmdsub_body() { 324303980Sngie atf_check -s exit:0 -o inline:'1 + 1 = 2\n' -e empty \ 325303980Sngie ${TEST_SH} -c 'echo 1 + 1 = $( echo $(( 1 + 1 )) )' 326303980Sngie atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \ 327303980Sngie ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = $( echo $(( X * Y )) )' 328303980Sngie atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \ 329303980Sngie ${TEST_SH} -c 'X=2; Y=3; echo Y % X = $( echo $(( $Y % $X )) )' 330303980Sngie} 331303980Sngie 332303980Sngieatf_test_case m_arithmetic_in_backticks 333303980Sngiem_arithmetic_in_backticks_head() { 334303980Sngie atf_set "descr" "Checks that arithmetic works in old style cmd sub" 335303980Sngie} 336303980Sngiem_arithmetic_in_backticks_body() { 337303980Sngie atf_check -s exit:0 -o inline:'2 + 3 = 5\n' -e empty \ 338303980Sngie ${TEST_SH} -c 'echo 2 + 3 = ` echo $(( 2 + 3 )) `' 339303980Sngie atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \ 340303980Sngie ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = ` echo $(( X * Y )) `' 341303980Sngie atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \ 342303980Sngie ${TEST_SH} -c 'X=2; Y=3; echo Y % X = ` echo $(( $Y % $X )) `' 343303980Sngie} 344303980Sngie 345303980Sngieatf_test_case n_cmdsub_in_arithmetic 346303980Sngien_cmdsub_in_arithmetic_head() { 347303980Sngie atf_set "descr" "Tests uses of command substitutions in arithmetic" 348303980Sngie} 349303980Sngien_cmdsub_in_arithmetic_body() { 350303980Sngie atf_check -s exit:0 -o inline:'7\n' -e empty \ 351303980Sngie ${TEST_SH} -c 'echo $(( $( echo 3 ) $( echo + ) $( echo 4 ) ))' 352303980Sngie atf_check -s exit:0 -o inline:'11\n7\n18\n4\n1\n' -e empty \ 353303980Sngie ${TEST_SH} -c \ 354303980Sngie 'for op in + - \* / % 355303980Sngie do 356303980Sngie echo $(( $( echo 9 ) $( echo "${op}" ) $( echo 2 ) )) 357303980Sngie done' 358303980Sngie} 359303980Sngie 360303980Sngieatf_test_case o_backticks_in_arithmetic 361303980Sngieo_backticks_in_arithmetic_head() { 362303980Sngie atf_set "descr" "Tests old style cmd sub used in arithmetic" 363303980Sngie} 364303980Sngieo_backticks_in_arithmetic_body() { 365303980Sngie atf_check -s exit:0 -o inline:'33\n' -e empty \ 366303980Sngie ${TEST_SH} -c 'echo $(( `echo 77` `echo -` `echo 44`))' 367303980Sngie atf_check -s exit:0 -o inline:'14\n8\n33\n3\n2\n' -e empty \ 368303980Sngie ${TEST_SH} -c \ 369303980Sngie 'for op in + - \* / % 370303980Sngie do 371303980Sngie echo $((`echo 11``echo "${op}"``echo 3`)) 372303980Sngie done' 373303980Sngie} 374303980Sngie 375303980Sngieatf_test_case p_cmdsub_in_heredoc 376303980Sngiep_cmdsub_in_heredoc_head() { 377303980Sngie atf_set "descr" "Checks that cmdsubs work inside a here document" 378303980Sngie} 379303980Sngiep_cmdsub_in_heredoc_body() { 380303980Sngie atf_require_prog cat 381303980Sngie 382303980Sngie atf_check -s exit:0 -o inline:'line 1+1\nline 2\nline 3\n' -e empty \ 383303980Sngie ${TEST_SH} -c \ 384303980Sngie 'cat <<- EOF 385303980Sngie $( echo line 1 )$( echo +1 ) 386303980Sngie $( echo line 2;echo line 3 ) 387303980Sngie EOF' 388303980Sngie} 389303980Sngie 390303980Sngieatf_test_case q_backticks_in_heredoc 391303980Sngieq_backticks_in_heredoc_head() { 392303980Sngie atf_set "descr" "Checks that old style cmdsubs work in here docs" 393303980Sngie} 394303980Sngieq_backticks_in_heredoc_body() { 395303980Sngie atf_require_prog cat 396303980Sngie 397303980Sngie atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ 398303980Sngie ${TEST_SH} -c \ 399303980Sngie 'cat <<- EOF 400303980Sngie `echo Mary ` `echo had a ` 401303980Sngie ` echo little; echo lamb ` 402303980Sngie EOF' 403303980Sngie} 404303980Sngie 405303980Sngieatf_test_case r_heredoc_in_cmdsub 406303980Sngier_heredoc_in_cmdsub_head() { 407303980Sngie atf_set "descr" "Checks that here docs work inside cmd subs" 408303980Sngie} 409303980Sngier_heredoc_in_cmdsub_body() { 410303980Sngie atf_require_prog cat 411303980Sngie 412303980Sngie atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ 413303980Sngie ${TEST_SH} -c 'echo "$( cat <<- \EOF 414303980Sngie Mary had a 415303980Sngie little 416303980Sngie lamb 417303980Sngie EOF 418303980Sngie )"' 419303980Sngie 420303980Sngie atf_check -s exit:0 -e empty \ 421303980Sngie -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \ 422303980Sngie ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF 423303980Sngie Mary had ${N} 424303980Sngie little 425303980Sngie lamb$( [ $N -gt 1 ] && echo s ) 426303980Sngie EOF 427303980Sngie )"; done' 428303980Sngie 429303980Sngie 430303980Sngie atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \ 431303980Sngie ${TEST_SH} -c 'echo "$( cat <<- EOF 432303980Sngie A Calculation: 433303980Sngie 2 * 7 = $(( 2 * 7 )) 434303980Sngie EOF 435303980Sngie )"' 436303980Sngie} 437303980Sngie 438303980Sngieatf_test_case s_heredoc_in_backticks 439303980Sngies_heredoc_in_backticks_head() { 440303980Sngie atf_set "descr" "Checks that here docs work inside old style cmd subs" 441303980Sngie} 442303980Sngies_heredoc_in_backticks_body() { 443303980Sngie atf_require_prog cat 444303980Sngie 445303980Sngie atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \ 446303980Sngie ${TEST_SH} -c 'echo ` cat <<- \EOF 447303980Sngie Mary had a 448303980Sngie little 449303980Sngie lamb 450303980Sngie EOF 451303980Sngie `' 452303980Sngie 453303980Sngie atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \ 454303980Sngie ${TEST_SH} -c 'echo "` cat <<- EOF 455303980Sngie A Calculation: 456303980Sngie 17 / 3 = $(( 17 / 3 )) 457303980Sngie EOF 458303980Sngie `"' 459303980Sngie} 460303980Sngie 461303980Sngieatf_test_case t_nested_cmdsubs_in_heredoc 462303980Sngiet_nested_cmdsubs_in_heredoc_head() { 463303980Sngie atf_set "descr" "Checks nested command substitutions in here docs" 464303980Sngie} 465303980Sngiet_nested_cmdsubs_in_heredoc_body() { 466303980Sngie atf_require_prog cat 467303980Sngie atf_require_prog rm 468303980Sngie 469303980Sngie rm -f * 2>/dev/null || : 470303980Sngie echo "Hello" > File 471303980Sngie 472303980Sngie atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ 473303980Sngie ${TEST_SH} -c 'cat <<- EOF 474303980Sngie $(cat File) U 475303980Sngie $( V=$(cat File); echo "${V%lo}p" ) me! 476303980Sngie EOF' 477303980Sngie 478303980Sngie rm -f * 2>/dev/null || : 479303980Sngie echo V>V ; echo A>A; echo R>R 480303980Sngie echo Value>VAR 481303980Sngie 482303980Sngie atf_check -s exit:0 -o inline:'$2.50\n' -e empty \ 483303980Sngie ${TEST_SH} -c 'cat <<- EOF 484303980Sngie $(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}))) 485303980Sngie EOF' 486303980Sngie} 487303980Sngie 488303980Sngieatf_test_case u_nested_backticks_in_heredoc 489303980Sngieu_nested_backticks_in_heredoc_head() { 490303980Sngie atf_set "descr" "Checks nested old style cmd subs in here docs" 491303980Sngie} 492303980Sngieu_nested_backticks_in_heredoc_body() { 493303980Sngie atf_require_prog cat 494303980Sngie atf_require_prog rm 495303980Sngie 496303980Sngie rm -f * 2>/dev/null || : 497303980Sngie echo "Hello" > File 498303980Sngie 499303980Sngie atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ 500303980Sngie ${TEST_SH} -c 'cat <<- EOF 501303980Sngie `cat File` U 502303980Sngie `V=\`cat File\`; echo "${V%lo}p" ` me! 503303980Sngie EOF' 504303980Sngie 505303980Sngie rm -f * 2>/dev/null || : 506303980Sngie echo V>V ; echo A>A; echo R>R 507303980Sngie echo Value>VAR 508303980Sngie 509303980Sngie atf_check -s exit:0 -o inline:'$5.20\n' -e empty \ 510303980Sngie ${TEST_SH} -c 'cat <<- EOF 511303980Sngie `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}\\\`\`` 512303980Sngie EOF' 513303980Sngie} 514303980Sngie 515303980Sngieatf_test_case v_cmdsub_paren_tests 516303980Sngiev_cmdsub__paren_tests_head() { 517303980Sngie atf_set "descr" "tests with cmdsubs containing embedded ')'" 518303980Sngie} 519303980Sngiev_cmdsub_paren_tests_body() { 520303980Sngie 521303980Sngie # Tests from: 522303980Sngie # http://www.in-ulm.de/~mascheck/various/cmd-subst/ 523303980Sngie # (slightly modified.) 524303980Sngie 525303980Sngie atf_check -s exit:0 -o inline:'A.1\n' -e empty ${TEST_SH} -c \ 526303980Sngie 'echo $( 527303980Sngie case x in x) echo A.1;; esac 528303980Sngie )' 529303980Sngie 530303980Sngie atf_check -s exit:0 -o inline:'A.2\n' -e empty ${TEST_SH} -c \ 531303980Sngie 'echo $( 532303980Sngie case x in x) echo A.2;; esac # comment 533303980Sngie )' 534303980Sngie 535303980Sngie atf_check -s exit:0 -o inline:'A.3\n' -e empty ${TEST_SH} -c \ 536303980Sngie 'echo $( 537303980Sngie case x in (x) echo A.3;; esac 538303980Sngie )' 539303980Sngie 540303980Sngie atf_check -s exit:0 -o inline:'A.4\n' -e empty ${TEST_SH} -c \ 541303980Sngie 'echo $( 542303980Sngie case x in (x) echo A.4;; esac # comment 543303980Sngie )' 544303980Sngie 545303980Sngie atf_check -s exit:0 -o inline:'A.5\n' -e empty ${TEST_SH} -c \ 546303980Sngie 'echo $( 547303980Sngie case x in (x) echo A.5 548303980Sngie esac 549303980Sngie )' 550303980Sngie 551303980Sngie atf_check -s exit:0 -o inline:'B: quoted )\n' -e empty ${TEST_SH} -c \ 552303980Sngie 'echo $( 553303980Sngie echo '\''B: quoted )'\'' 554303980Sngie )' 555303980Sngie 556303980Sngie atf_check -s exit:0 -o inline:'C: comment then closing paren\n' \ 557303980Sngie -e empty ${TEST_SH} -c \ 558303980Sngie 'echo $( 559303980Sngie echo C: comment then closing paren # ) 560303980Sngie )' 561303980Sngie 562303980Sngie atf_check -s exit:0 -o inline:'D.1: here-doc with )\n' \ 563303980Sngie -e empty ${TEST_SH} -c \ 564303980Sngie 'echo $( 565303980Sngie cat <<-\eof 566303980Sngie D.1: here-doc with ) 567303980Sngie eof 568303980Sngie )' 569303980Sngie 570303980Sngie # D.2 is a bogus test. 571303980Sngie 572303980Sngie atf_check -s exit:0 -o inline:'D.3: here-doc with \()\n' \ 573303980Sngie -e empty ${TEST_SH} -c \ 574303980Sngie 'echo $( 575303980Sngie cat <<-\eof 576303980Sngie D.3: here-doc with \() 577303980Sngie eof 578303980Sngie )' 579303980Sngie 580303980Sngie atf_check -s exit:0 -e empty \ 581303980Sngie -o inline:'E: here-doc terminated with a parenthesis ("academic")\n' \ 582303980Sngie ${TEST_SH} -c \ 583303980Sngie 'echo $( 584303980Sngie cat <<-\) 585303980Sngie E: here-doc terminated with a parenthesis ("academic") 586303980Sngie ) 587303980Sngie )' 588303980Sngie 589303980Sngie atf_check -s exit:0 -e empty \ 590303980Sngie-o inline:'F.1: here-doc embed with unbal single, back- or doublequote '\''\n' \ 591303980Sngie ${TEST_SH} -c \ 592303980Sngie 'echo $( 593303980Sngie cat <<-"eof" 594303980Sngie F.1: here-doc embed with unbal single, back- or doublequote '\'' 595303980Sngie eof 596303980Sngie )' 597303980Sngie atf_check -s exit:0 -e empty \ 598303980Sngie -o inline:'F.2: here-doc embed with unbal single, back- or doublequote "\n' \ 599303980Sngie ${TEST_SH} -c \ 600303980Sngie 'echo $( 601303980Sngie cat <<-"eof" 602303980Sngie F.2: here-doc embed with unbal single, back- or doublequote " 603303980Sngie eof 604303980Sngie )' 605303980Sngie atf_check -s exit:0 -e empty \ 606303980Sngie -o inline:'F.3: here-doc embed with unbal single, back- or doublequote `\n' \ 607303980Sngie ${TEST_SH} -c \ 608303980Sngie 'echo $( 609303980Sngie cat <<-"eof" 610303980Sngie F.3: here-doc embed with unbal single, back- or doublequote ` 611303980Sngie eof 612303980Sngie )' 613303980Sngie 614303980Sngie atf_check -s exit:0 -e empty -o inline:'G: backslash at end of line\n' \ 615303980Sngie ${TEST_SH} -c \ 616303980Sngie 'echo $( 617303980Sngie echo G: backslash at end of line # \ 618303980Sngie )' 619303980Sngie 620303980Sngie atf_check -s exit:0 -e empty \ 621303980Sngie -o inline:'H: empty command-substitution\n' \ 622303980Sngie ${TEST_SH} -c 'echo H: empty command-substitution $( )' 623303980Sngie} 624303980Sngie 625303980Sngieatf_test_case w_heredoc_outside_cmdsub 626303980Sngiew_heredoc_outside_cmdsub_head() { 627303980Sngie atf_set "descr" "Checks that here docs work inside cmd subs" 628303980Sngie} 629303980Sngiew_heredoc_outside_cmdsub_body() { 630303980Sngie atf_require_prog cat 631303980Sngie 632303980Sngie atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ 633303980Sngie ${TEST_SH} -c 'echo "$( cat <<- \EOF )" 634303980Sngie Mary had a 635303980Sngie little 636303980Sngie lamb 637303980Sngie EOF 638303980Sngie ' 639303980Sngie 640303980Sngie atf_check -s exit:0 -e empty \ 641303980Sngie -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \ 642303980Sngie ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF )" 643303980Sngie Mary had ${N} 644303980Sngie little 645303980Sngie lamb$( [ $N -gt 1 ] && echo s ) 646303980Sngie EOF 647303980Sngie done' 648303980Sngie 649303980Sngie 650303980Sngie atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \ 651303980Sngie ${TEST_SH} -c 'echo "$( cat <<- EOF)" 652303980Sngie A Calculation: 653303980Sngie 2 * 7 = $(( 2 * 7 )) 654303980Sngie EOF 655303980Sngie ' 656303980Sngie} 657303980Sngie 658303980Sngieatf_test_case x_heredoc_outside_backticks 659303980Sngiex_heredoc_outside_backticks_head() { 660303980Sngie atf_set "descr" "Checks that here docs work inside old style cmd subs" 661303980Sngie} 662303980Sngiex_heredoc_outside_backticks_body() { 663303980Sngie atf_require_prog cat 664303980Sngie 665303980Sngie atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \ 666303980Sngie ${TEST_SH} -c 'echo ` cat <<- \EOF ` 667303980Sngie Mary had a 668303980Sngie little 669303980Sngie lamb 670303980Sngie EOF 671303980Sngie ' 672303980Sngie 673303980Sngie atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \ 674303980Sngie ${TEST_SH} -c 'echo "` cat <<- EOF `" 675303980Sngie A Calculation: 676303980Sngie 17 / 3 = $(( 17 / 3 )) 677303980Sngie EOF 678303980Sngie ' 679303980Sngie} 680303980Sngie 681303980Sngieatf_test_case t_nested_cmdsubs_in_heredoc 682303980Sngiet_nested_cmdsubs_in_heredoc_head() { 683303980Sngie atf_set "descr" "Checks nested command substitutions in here docs" 684303980Sngie} 685303980Sngiet_nested_cmdsubs_in_heredoc_body() { 686303980Sngie atf_require_prog cat 687303980Sngie atf_require_prog rm 688303980Sngie 689303980Sngie rm -f * 2>/dev/null || : 690303980Sngie echo "Hello" > File 691303980Sngie 692303980Sngie atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ 693303980Sngie ${TEST_SH} -c 'cat <<- EOF 694303980Sngie $(cat File) U 695303980Sngie $( V=$(cat File); echo "${V%lo}p" ) me! 696303980Sngie EOF' 697303980Sngie 698303980Sngie rm -f * 2>/dev/null || : 699303980Sngie echo V>V ; echo A>A; echo R>R 700303980Sngie echo Value>VAR 701303980Sngie 702303980Sngie atf_check -s exit:0 -o inline:'$2.50\n' -e empty \ 703303980Sngie ${TEST_SH} -c 'cat <<- EOF 704303980Sngie $(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}))) 705303980Sngie EOF' 706303980Sngie} 707303980Sngie 708303980Sngieatf_test_case z_absurd_heredoc_cmdsub_combos 709303980Sngiez_absurd_heredoc_cmdsub_combos_head() { 710303980Sngie atf_set "descr" "perverse and unusual cmd substitutions & more" 711303980Sngie} 712303980Sngiez_absurd_heredoc_cmdsub_combos_body() { 713303980Sngie 714303980Sngie echo "Help!" > help 715303980Sngie 716303980Sngie # This version works in NetBSD (& FreeBSD)'s sh (and most others) 717303980Sngie atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c ' 718303980Sngie cat <<- EOF 719303980Sngie $( 720303980Sngie cat <<- STOP 721303980Sngie $( 722303980Sngie cat `echo help` 723303980Sngie ) 724303980Sngie STOP 725303980Sngie ) 726303980Sngie $( 727303980Sngie cat <<- END 4<<-TRASH 728303980Sngie Me $(( 1 + 1 )) 729303980Sngie END 730303980Sngie This is unused noise! 731303980Sngie TRASH 732303980Sngie ) 733303980Sngie EOF 734303980Sngie ' 735303980Sngie 736303980Sngie # atf_expect_fail "PR bin/50993 - heredoc parsing done incorrectly" 737303980Sngie atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c ' 738303980Sngie cat <<- EOF 739303980Sngie $( 740303980Sngie cat << STOP 741303980Sngie $( 742303980Sngie cat `echo help` 743303980Sngie ) 744303980Sngie STOP 745303980Sngie ) 746303980Sngie $( 747303980Sngie cat <<- END 4<<TRASH 748303980Sngie Me $(( 1 + 1 )) 749303980Sngie END 750303980Sngie This is unused noise! 751303980Sngie TRASH 752303980Sngie ) 753303980Sngie EOF 754303980Sngie ' 755303980Sngie} 756303980Sngie 757303980Sngieatf_init_test_cases() { 758303980Sngie atf_add_test_case a_basic_cmdsub 759303980Sngie atf_add_test_case b_basic_backticks 760303980Sngie atf_add_test_case c_nested_cmdsub 761303980Sngie atf_add_test_case d_nested_backticks 762303980Sngie atf_add_test_case e_perverse_mixing 763303980Sngie atf_add_test_case f_redirect_in_cmdsub 764303980Sngie atf_add_test_case g_redirect_in_backticks 765303980Sngie atf_add_test_case h_vars_in_cmdsub 766303980Sngie atf_add_test_case i_vars_in_backticks 767303980Sngie atf_add_test_case j_cmdsub_in_varexpand 768303980Sngie atf_add_test_case k_backticks_in_varexpand 769303980Sngie atf_add_test_case l_arithmetic_in_cmdsub 770303980Sngie atf_add_test_case m_arithmetic_in_backticks 771303980Sngie atf_add_test_case n_cmdsub_in_arithmetic 772303980Sngie atf_add_test_case o_backticks_in_arithmetic 773303980Sngie atf_add_test_case p_cmdsub_in_heredoc 774303980Sngie atf_add_test_case q_backticks_in_heredoc 775303980Sngie atf_add_test_case r_heredoc_in_cmdsub 776303980Sngie atf_add_test_case s_heredoc_in_backticks 777303980Sngie atf_add_test_case t_nested_cmdsubs_in_heredoc 778303980Sngie atf_add_test_case u_nested_backticks_in_heredoc 779303980Sngie atf_add_test_case v_cmdsub_paren_tests 780303980Sngie atf_add_test_case w_heredoc_outside_cmdsub 781303980Sngie atf_add_test_case x_heredoc_outside_backticks 782303980Sngie atf_add_test_case z_absurd_heredoc_cmdsub_combos 783303980Sngie} 784