| # |
| # A suite of tests for bash word expansions |
| # |
| # This tests parameter and variable expansion, with an empahsis on |
| # proper quoting behavior. |
| # |
| # Chet Ramey |
| |
| # |
| # If you comment out the body of this function, you can do a diff against |
| # `expansion-tests.right' to see if the shell is behaving correctly |
| # |
| expect() |
| { |
| echo expect "$@" |
| } |
| |
| # Test the substitution quoting characters (CTLESC and CTLNUL) in different |
| # combinations |
| |
| expect "<^A>" |
| recho `echo ''` |
| expect "<^A>" |
| recho `echo ""` |
| expect "<^B>" |
| recho `echo ''` |
| expect "<^B>" |
| recho `echo ""` |
| expect "<^A>" |
| recho `echo ` |
| expect "<^B>" |
| recho `echo ` |
| |
| # Test null strings without variable expansion |
| expect "<abcdefgh>" |
| recho abcd""efgh |
| expect "<abcdefgh>" |
| recho abcd''efgh |
| expect "<abcdefgh>" |
| recho ""abcdefgh |
| expect "<abcdefgh>" |
| recho ''abcdefgh |
| expect "<abcd>" |
| recho abcd"" |
| expect "<abcd>" |
| recho abcd'' |
| |
| # Test the quirky behavior of $@ in "" |
| expect nothing |
| recho "$@" |
| expect "< >" |
| recho " $@" |
| expect "<-->" |
| recho "-${@}-" |
| |
| # Test null strings with variable expansion that fails |
| expect '<>' |
| recho $xxx"" |
| expect '<>' |
| recho ""$xxx |
| expect '<>' |
| recho $xxx'' |
| expect '<>' |
| recho ''$xxx |
| expect '<>' |
| recho $xxx""$yyy |
| expect '<>' |
| recho $xxx''$yyy |
| |
| # Test null strings with variable expansion that succeeds |
| xxx=abc |
| yyy=def |
| |
| expect '<abc>' |
| recho $xxx"" |
| expect '<abc>' |
| recho ""$xxx |
| expect '<abc>' |
| recho $xxx'' |
| expect '<abc>' |
| recho ''$xxx |
| expect '<abcdef>' |
| recho $xxx""$yyy |
| expect '<abcdef>' |
| recho $xxx''$yyy |
| |
| unset xxx yyy |
| |
| # Test the unquoted special quoting characters |
| expect "<^A>" |
| recho |
| expect "<^B>" |
| recho |
| expect "<^A>" |
| recho "" |
| expect "<^B>" |
| recho "" |
| expect "<^A>" |
| recho '' |
| expect "<^B>" |
| recho '' |
| |
| # Test expansion of a variable that is unset |
| expect nothing |
| recho $xxx |
| expect '<>' |
| recho "$xxx" |
| |
| expect nothing |
| recho "$xxx${@}" |
| |
| # Test empty string expansion |
| expect '<>' |
| recho "" |
| expect '<>' |
| recho '' |
| |
| # Test command substitution with (disabled) history substitution |
| expect '<Hello World!>' |
| # set +H |
| recho "`echo \"Hello world!\"`" |
| |
| # Test some shell special characters |
| expect '<`>' |
| recho "\`" |
| expect '<">' |
| recho "\"" |
| expect '<\^A>' |
| recho "\" |
| |
| expect '<\$>' |
| recho "\\$" |
| |
| expect '<\\>' |
| recho "\\\\" |
| |
| # This should give argv[1] = a argv[2] = b |
| expect '<a> <b>' |
| FOO=`echo 'a b' | tr ' ' '\012'` |
| recho $FOO |
| |
| # This should give argv[1] = ^A argv[2] = ^B |
| expect '<^A> <^B>' |
| FOO=`echo ' ' | tr ' ' '\012'` |
| recho $FOO |
| |
| # Test quoted and unquoted globbing characters |
| expect '<**>' |
| recho "*"* |
| |
| expect '<\.\./*/>' |
| recho "\.\./*/" |
| |
| # Test patterns that come up when the shell quotes funny character |
| # combinations |
| expect '<^A^B^A^B>' |
| recho '' |
| expect '<^A^A>' |
| recho '' |
| expect '<^A^B>' |
| recho '' |
| expect '<^A^A^B>' |
| recho '' |
| |
| # More tests of "$@" |
| set abc def ghi jkl |
| expect '< abc> <def> <ghi> <jkl >' |
| recho " $@ " |
| expect '< abc> <def> <ghi> <jkl >' |
| recho "${1+ $@ }" |
| |
| set abc def ghi jkl |
| expect '<--abc> <def> <ghi> <jkl-->' |
| recho "--$@--" |
| |
| set "a b" cd ef gh |
| expect '<a b> <cd> <ef> <gh>' |
| recho ${1+"$@"} |
| expect '<a b> <cd> <ef> <gh>' |
| recho ${foo:-"$@"} |
| expect '<a b> <cd> <ef> <gh>' |
| recho "${@}" |
| |
| expect '< >' |
| recho " " |
| expect '< - >' |
| recho " - " |
| |
| # Test combinations of different types of quoting in a fully-quoted string |
| # (so the WHOLLY_QUOTED tests fail and it doesn't get set) |
| expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>' |
| recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/" |
| |
| # Test the various Posix parameter expansions |
| |
| expect '<foo bar>' |
| recho "${x:-$(echo "foo bar")}" |
| expect '<foo> <bar>' |
| recho ${x:-$(echo "foo bar")} |
| |
| unset X |
| expect '<abc>' |
| recho ${X:=abc} |
| expect '<abc>' |
| recho $X |
| |
| set a b c |
| expect '<posix>' |
| recho ${3:+posix} |
| |
| POSIX=/usr/posix |
| expect '<10>' |
| recho ${#POSIX} |
| |
| # remove shortest trailing match |
| x=file.c |
| expect '<file.o>' |
| recho ${x%.c}.o |
| |
| # remove longest trailing match |
| x=posix/src/std |
| expect '<posix>' |
| recho ${x%%/*} |
| |
| # remove shortest leading pattern |
| x=$HOME/src/cmd |
| expect '</src/cmd>' |
| recho ${x#$HOME} |
| |
| # remove longest leading pattern |
| x=/one/two/three |
| expect '<three>' |
| recho ${x##*/} |
| |
| # pattern removal of patterns that don't match |
| z=abcdef |
| |
| expect '<abcdef>' |
| recho ${z#xyz} |
| expect '<abcdef>' |
| recho ${z##xyz} |
| |
| expect '<abcdef>' |
| recho ${z%xyz} |
| expect '<abcdef>' |
| recho ${z%%xyz} |
| |
| # Command substitution and the quirky differences between `` and $() |
| |
| expect '<\$x>' |
| recho '\$x' |
| |
| expect '<$x>' |
| recho `echo '\$x'` |
| |
| expect '<\$x>' |
| recho $(echo '\$x') |
| |
| # The difference between $* "$*" and "$@" |
| |
| set "abc" "def ghi" "jkl" |
| |
| expect '<abc> <def> <ghi> <jkl>' |
| recho $* |
| |
| expect '<abc def ghi jkl>' |
| recho "$*" |
| |
| OIFS="$IFS" |
| IFS=":$IFS" |
| |
| # The special behavior of "$*", using the first character of $IFS as separator |
| expect '<abc:def ghi:jkl>' |
| recho "$*" |
| |
| IFS="$OIFS" |
| |
| expect '<abc> <def ghi> <jkl>' |
| recho "$@" |
| |
| expect '<xxabc> <def ghi> <jklyy>' |
| recho "xx$@yy" |
| |
| expect '<abc> <def ghi> <jklabc> <def ghi> <jkl>' |
| recho "$@$@" |
| |
| foo=abc |
| bar=def |
| |
| expect '<abcdef>' |
| recho "$foo""$bar" |
| |
| unset foo |
| set $foo bar '' xyz "$foo" abc |
| |
| expect '<bar> <> <xyz> <> <abc>' |
| recho "$@" |
| |
| # More tests of quoting and deferred evaluation |
| |
| foo=10 x=foo |
| y='$'$x |
| expect '<$foo>' |
| recho $y |
| eval y='$'$x |
| expect '<10>' |
| recho $y |
| |
| # case statements |
| |
| NL=' |
| ' |
| x='ab |
| cd' |
| |
| expect '<newline expected>' |
| case "$x" in |
| *$NL*) recho "newline expected" ;; |
| esac |
| |
| expect '<got it>' |
| case \? in |
| *"?"*) recho "got it" ;; |
| esac |
| |
| expect '<got it>' |
| case \? in |
| *\?*) recho "got it" ;; |
| esac |
| |
| set one two three four five |
| expect '<one> <three> <five>' |
| recho $1 $3 ${5} $8 ${9} |
| |
| # length tests on positional parameters and some special parameters |
| |
| expect '<5> <5>' |
| recho $# ${#} |
| expect '<3>' |
| recho ${#1} |
| expect '<1>' |
| recho ${##} |
| expect '<1>' |
| recho ${#?} |
| expect '<5>' |
| recho ${#@} |
| expect '<5>' |
| recho ${#*} |
| expect '<5>' |
| recho "${#@}" |
| expect '<5>' |
| recho "${#*}" |
| |
| expect '<42>' |
| recho $((28 + 14)) |
| expect '<26>' |
| recho $[ 13 * 2 ] |
| |
| expect '<\>' |
| recho `echo \\\\` |
| |
| expect '<~>' |
| recho '~' |
| |
| expect nothing |
| recho $! |
| expect nothing |
| recho ${!} |
| |
| # test word splitting of assignment statements not preceding a command |
| a="a b c d e" |
| declare b=$a |
| expect '<a> <b> <c> <d> <e>' |
| recho $b |
| |
| a="a?b?c" |
| |
| echo ${a//\\?/ } |
| |
| echo ${a//\?/ } |
| |
| ${THIS_SH} ./exp1.sub |
| |
| ${THIS_SH} ./exp2.sub |