bash-5.2-alpha release

This commit is contained in:
Chet Ramey
2022-01-20 15:06:05 -05:00
parent 9439ce094c
commit 4491c03014
409 changed files with 63491 additions and 54851 deletions
+1
View File
@@ -2,6 +2,7 @@ alias: 0
alias: 0
./alias.tests: line 38: qfoo: command not found
quux
hi
bar
value
bar
+8
View File
@@ -49,6 +49,14 @@ foo bar
unalias foo bar baz
# post bash-5.1 problems with compound array assignment during multiline
# alias expansion
alias foo='a=() b=""
for i in 1; do echo hi; done'
foo
unalias foo
${THIS_SH} ./alias1.sub
${THIS_SH} ./alias2.sub
${THIS_SH} ./alias3.sub
+2 -2
View File
@@ -259,5 +259,5 @@ efg
42
42
42
./arith.tests: line 327: 'foo' : syntax error: operand expected (error token is "'foo' ")
./arith.tests: line 331: b[c]d: syntax error in expression (error token is "d")
./arith.tests: line 330: 'foo' : syntax error: operand expected (error token is "'foo' ")
./arith.tests: line 333: b[c]d: syntax error in expression (error token is "d")
+3 -1
View File
@@ -322,10 +322,12 @@ printf "%u\n" $n
echo $(( 16#$(printf "%x\n" $n) ))
echo $(( 16#$(printf "%X\n" $n) ))
# allow reserved words after an arithmetic command just because
if ((expr)) then ((expr)) fi
# these are errors
foo=1
echo $(( 'foo' ))
# causes longjmp botches through bash-2.05b
a[b[c]d]=e
Executable → Regular
View File
+41 -19
View File
@@ -67,6 +67,7 @@ declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="t
declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
declare -ar c
declare -a d=([1]="test test")
declare -a e=()
declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
./array.tests: line 135: unset: ps1: not an array variable
./array.tests: line 139: declare: c: cannot destroy array variables in this way
@@ -84,6 +85,7 @@ declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="t
declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
declare -ar c
declare -a d=([1]="test test")
declare -a e=()
declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
declare -a rv=([0]="this" [1]="is" [2]="a" [3]="test" [4]="of" [5]="read" [6]="using" [7]="arrays")
abde
@@ -381,6 +383,8 @@ strlen(4four) = 5
1 2 0 3
1 2 0 3
1 2 0 3
declare -ai arr=([0]="2" [1]="4" [2]="6")
declare -a arr=([0]="hello" [1]="world")
foo index 1: ok
foo index 2: ok
foo: implicit reference to element 0: ok
@@ -492,8 +496,8 @@ x b c
declare -a a=([1]="2" [2]="3" [3]="4")
abcd
unset
./array21.sub: line 30: typeset: a: not found
./array21.sub: line 33: typeset: A: not found
declare -a a=()
declare -A A=([four]="4" [two]="2" [three]="3" [one]="1" )
declare -a a=()
declare -A A=()
declare -a foo=([0]="1" [1]="(4 5 6)" [2]="3")
@@ -520,13 +524,11 @@ argv[1] = <y>
<X> <X> <X> <X>
./array23.sub: line 22: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 23: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
foo
0
foo
foo
foo
6
./array23.sub: line 34: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 24: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 26: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 30: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 33: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 34: $index: syntax error: operand expected (error token is "$index")
./array23.sub: line 35: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
0
0
@@ -743,23 +745,43 @@ argv[1] = <b>
argv[2] = <a>
argv[1] = <b+a>
7
./array27.sub: line 24: a[]]=7 : syntax error: invalid arithmetic operator (error token is "]=7 ")
7
declare -A A=([$'\t']="2" [" "]="2" )
./array27.sub: line 36: ((: A[]]=2 : syntax error: invalid arithmetic operator (error token is "]=2 ")
declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["@"]="2" )
./array27.sub: line 45: A[]]: bad array subscript
declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
./array27.sub: line 52: read: `A[]]': not a valid identifier
declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
./array27.sub: line 53: A[]]: bad array subscript
./array27.sub: line 60: printf: `A[]]': not a valid identifier
declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
./array27.sub: line 61: declare: `A[]]=X': not a valid identifier
./array27.sub: line 68: declare: `A[]]=X': not a valid identifier
declare -A A=(["*"]="X" ["@"]="X" )
./array27.sub: line 76: declare: `A[]]=X': not a valid identifier
declare -A A=(["*"]="X" ["@"]="X" )
./array27.sub: line 69: declare: `A[]]=X': not a valid identifier
./array27.sub: line 69: A[*]: bad array subscript
./array27.sub: line 69: A[@]: bad array subscript
declare -A A
declare -a bug4=([0]="" [1]="5" [2]="" [3]="1" [4]="")
declare -a bug=([0]="" [1]="5" [2]="" [3]="1" [4]="")
declare -a bug2=([0]="")
declare -a bug3=([0]="" [1]="5" [2]="" [3]="1" [4]="")
declare -a not_bug=([0]="no" [1]="nulls")
declare -a workaround=([0]="")
declare -a var=([0]=$'\001\001\001\001')
declare -A v2=([$'\001']=$'ab\001c' )
declare -a foo=([0]=$'\001\001\001\001')
declare -A foo=([$'\001']=$'ab\001c' )
declare -a foo=([0]=$'\001\001\001\001')
declare -a foo=([0]=$'\001\001\001\001')
declare -A foo=([v]=$'\001\001\001\001' )
declare -A foo=([v]=$'\001\001\001\001' )
declare -A foo=([$'\001']=$'ab\001c' )
declare -A foo=([$'\001']=$'ab\001c' )
foo
declare -a a=([42]="foo")
foo
declare -a a=([42]="foo")
7
declare -ai a=([42]="7")
42
declare -ai a=([42]="42")
FOO
declare -Au A=([Darwin]="FOO" )
FOO
declare -Au A=(["@"]="FOO" )
+2
View File
@@ -425,3 +425,5 @@ ${THIS_SH} ./array25.sub
${THIS_SH} ./array26.sub
${THIS_SH} ./array27.sub
${THIS_SH} ./array28.sub
${THIS_SH} ./array29.sub
${THIS_SH} ./array30.sub
+15
View File
@@ -35,3 +35,18 @@ func()
func
echo "${foo[@]}"
unset foo
# test options to declare that disable attributes that affect how values
# are expanded
#
# we already handle options that set attributes specially, so we should
# handle attributes that unset those attributes specially as well
unset arr
declare -i -a arr=(1+1 2+2 3+3)
declare -p arr
declare +i arr=(hello world)
declare -p arr
+7 -1
View File
@@ -38,6 +38,13 @@ done
declare -p A
unset A
declare -A A
for k in ']' '*' '@' $'\t' ' '; do
A[$k]=2
done
declare -p A
unset A
declare -A A
@@ -69,4 +76,3 @@ for k in ']' '*' '@'; do
declare "A[$k]=X"
done
declare -p A
+86
View File
@@ -0,0 +1,86 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Issues with CTLESC characters in array subscripts and values. Bash-5.1 and
# earlier didn't quote them correctly and therefore halved the number of
# CTLESCs.
declare -a var
var=( $'\x01\x01\x01\x01' )
declare -p var
declare -A v2
v2=( $'\x01' ab$'\x01'c )
declare -p v2
pv()
{
local -a foo
foo=( "${var[@]}" )
declare -p foo
}
pv
unset -f pv
pv()
{
local -A foo
eval foo=\( "${v2[@]@k}" \)
declare -p foo
}
pv
# these are wrong through bash-5.1; there is a fix tagged for bash-5.2
# when I uncomment that fix, these results will reflect it
pv1()
{
local -a foo=( "${var[@]}" )
declare -p foo
}
pv1
pv2()
{
local -a foo=( [0]="${var[@]}" )
declare -p foo
}
pv2
pv3()
{
local -A foo=( v "${var[@]}" )
declare -p foo
}
pv3
pv4()
{
local -A foo=( [v]="${var[@]}" )
declare -p foo
}
pv4
unset -f pv3 pv4
pv3()
{
local -A foo=( $'\x01' "${v2[@]}" )
declare -p foo
}
pv3
pv4()
{
local -A foo=( [$'\x01']="${v2[@]}" )
declare -p foo
}
pv4
+46
View File
@@ -0,0 +1,46 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
declare -a a
a=()
echo ${a[42]=foo}
declare -p a
a=()
echo ${a[$(echo 42)]=foo}
declare -p a
unset a
declare -ai a
a=()
echo ${a[42]=4+3}
declare -p a
a=()
echo ${a[$(echo 42)]=42}
declare -p a
unset a
declare -A A
declare -u A
A=()
echo ${A[$(echo Darwin)]=foo}
declare -p A
A=()
echo ${A[@]:=foo}
declare -p A
+162 -22
View File
@@ -16,25 +16,24 @@ declare -A wheat=([two]="b" [three]="c" [one]="a" [zero]="0" )
declare -A chaff=(["hello world"]="flip" [one]="10" [zero]="5" )
./assoc.tests: line 51: waste: readonly variable
./assoc.tests: line 52: unset: waste: cannot unset: readonly variable
./assoc.tests: line 53: chaff[*]: bad array subscript
./assoc.tests: line 54: [*]=12: invalid associative array key
declare -A chaff=(["hello world"]="flip" [one]="a" )
declare -A chaff=(["*"]="12" ["hello world"]="flip" [one]="a" )
flip
argv[1] = <multiple>
argv[2] = <words>
argv[3] = <12>
argv[4] = <flip>
argv[5] = <a>
argv[1] = <multiple words>
argv[2] = <12>
argv[3] = <flip>
argv[4] = <a>
argv[1] = <multiple words>
argv[2] = <flip>
argv[3] = <a>
argv[1] = <multiple>
argv[2] = <words>
argv[3] = <flip>
argv[4] = <a>
argv[1] = <multiple words flip a>
argv[3] = <12>
argv[4] = <flip>
argv[5] = <a>
argv[1] = <multiple words 12 flip a>
./assoc.tests: line 71: declare: chaff: cannot destroy array variables in this way
./assoc.tests: line 73: chaff[*]: bad array subscript
./assoc.tests: line 74: [*]=12: invalid associative array key
declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
argv[1] = <qux>
argv[2] = <qix>
@@ -200,11 +199,7 @@ declare -A hash=([key]="value1 value2" )
declare -A b=([")"]="" ["\""]="" ["]"]="" ["\\"]="" ["\`"]="" )
declare -A b=(["]"]="" ["\`"]="" )
declare -A dict=(["'"]="3" ["\""]="1" ["\\"]="4" ["\`"]="2" )
./assoc9.sub: line 36: unset: `dict[']': not a valid identifier
./assoc9.sub: line 36: unset: `dict["]': not a valid identifier
./assoc9.sub: line 36: unset: `dict[\]': not a valid identifier
./assoc9.sub: line 36: unset: `dict[`]': not a valid identifier
declare -A dict=(["'"]="3" ["\""]="1" ["\\"]="4" ["\`"]="2" )
declare -A dict=()
declare -A dict=(["'"]="3" ["\""]="1" ["\\"]="4" ["\`"]="2" )
declare -A dict=()
4
@@ -223,6 +218,14 @@ declare -A a=(["80's"]="Depeche Mode" )
declare -A a=(["\$(date >&2)"]="5" )
declare -A myarray=([foo]="bleh" ["foo[bar"]="bleh" )
foo
declare -A assoc=(["\$var"]="value" )
declare -A assoc=(["\$var"]="value" )
declare -A assoc=(["\$var"]="value" )
declare -A assoc=()
./assoc9.sub: line 154: typeset: `foo[foo]bar]=bax': not a valid identifier
foo]bar
bip
declare -A foo=(["foo]bar"]="bip" )
./assoc10.sub: line 14: declare: a: cannot convert indexed to associative array
f: declare -a a
./assoc10.sub: line 17: declare: a: cannot convert associative to indexed array
@@ -250,11 +253,148 @@ declare -A dict=(["?"]="quest" ["*"]="star" ["'"]="squote" ["\$"]="dol" ["\""]="
dict=( "?" "quest" "*" "star" "'" "squote" "\$" "dol" "\"" "dquote" "\\" "bslash" "@" "at" "}" "rbrace" "{" "lbrace" "\`" "bquote" )
declare -A foo=([two]="" [one]="1" )
foo=( two "" one "1" )
rparen dquote rbrace bs
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
")" "rparen" "\"" "dquote" "]" "rbrace" "\\" "bs"
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
rparen dquote rbracket bs
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
")" "rparen" "\"" "dquote" "]" "rbracket" "\\" "bs"
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -Arx foo=([two]="2" [three]="3" [one]="1" )
./assoc11.sub: line 90: foo: readonly variable
declare -A v1=(["1 2"]="3" )
declare -A v2=(["1 2"]="3" )
declare -A v3=(["1 2"]="3" )
declare -A v1=(["1 2"]="3 4 5" )
declare -A v2=(["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" )
declare -A v1=(["1 2"]="3 4 5" )
declare -A v2=(["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" )
declare -A v1=(["1 2"]="3 4 5" )
declare -A v2=(["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" )
declare -A v1=(["20 40 80"]="xtra" ["1 2"]="3 4 5" )
declare -A v2=(["20 40 80"]="xtra" ["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" ["\$xtra"]="xtra" )
declare -A v1=(["20 40 80"]="new xtra" ["1 2"]="3 4 5" )
declare -A v2=(["20 40 80"]="new xtra" ["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" ["\$xtra"]="new xtra" )
declare -A assoc=(["*"]="star" ["!"]="bang" ["@"]="at" )
at
star
declare -A a=(["@"]="at" )
./assoc13.sub: line 22: ia[@]: bad array subscript
declare -a ia
declare -A a=(["@"]="at2" )
declare -A a=(["@"]=" string" )
declare -A a=(["*"]="star2" ["@"]="at" )
declare -A assoc=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
argv[1] = <world>
argv[2] = <value with spaces>
argv[3] = <bar>
argv[4] = <1>
argv[1] = <hello>
argv[2] = <world>
argv[3] = <key with spaces>
argv[4] = <value with spaces>
argv[5] = <foo>
argv[6] = <bar>
argv[7] = <one>
argv[8] = <1>
argv[1] = <world value with spaces bar 1>
argv[1] = <hello world key with spaces value with spaces foo bar one 1>
argv[1] = <hello>
argv[2] = <world>
argv[3] = <key with spaces>
argv[4] = <value with spaces>
argv[5] = <one>
argv[6] = <1>
argv[7] = <foo>
argv[8] = <bar>
argv[1] = <'hello'>
argv[2] = <'world'>
argv[3] = <'key with spaces'>
argv[4] = <'value with spaces'>
argv[5] = <'one'>
argv[6] = <'1'>
argv[7] = <'foo'>
argv[8] = <'bar'>
argv[1] = <'hello'>
argv[2] = <'world'>
argv[3] = <'key with spaces'>
argv[4] = <'value with spaces'>
argv[5] = <'one'>
argv[6] = <'1'>
argv[7] = <'foo'>
argv[8] = <'bar'>
declare -A clone=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
declare -A posparams=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
declare -A var=([$'\001']=$'\001\001\001\001' )
declare -A v2=([$'\001']=$'\001\001\001\001' )
argv[1] = <^A>
argv[2] = <^A^A^A^A>
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -A var=([$'\001']=$'\001\001\001\001' )
argv[1] = <^A>
argv[2] = <^A^A^A^A>
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -A var=([$'\001']=$'\001\001\001\001' )
argv[1] = <^A>
argv[2] = <^A^A^A^A>
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -a var=([0]=$'\001\001\001\001')
argv[1] = <$'\001\001\001\001'>
declare -a foo=([0]=$'\001\001\001\001')
declare -a var=([0]=$'\001\001\001\001')
argv[1] = <$'\001\001\001\001'>
declare -a foo=([0]=$'\001\001\001\001')
declare -A var=([two]=$'ab\001cd' [one]=$'\001\001\001\001' )
declare -A foo=([two]=$'ab\001cd' [one]=$'\001\001\001\001' )
declare -A foo=([$'\001']=$'ab\001cd' )
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -A A=(["\$(echo Darwin ; echo stderr>&2)"]="darjeeling" [Darwin]="darjeeling" )
stderr
darjsharking
darjsharking
stderr
darj
darj
stderr
DARJEELING
DARJEELING
stderr
'darjeeling'
'darjeeling'
stderr
darjeel
darjeel
stderr
10
10
stderr
darjeeling
darjeeling
stderr
set
set
stderr
set
set
stderr
42
42
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
5: ok 1
+23 -1
View File
@@ -47,7 +47,7 @@ declare +i chaff
chaff[hello world]=flip
declare -p chaff
# TEST - errors
# TEST - no longer errors
waste[stuff]=other
unset waste
chaff[*]=12
@@ -244,3 +244,25 @@ ${THIS_SH} ./assoc10.sub
# test assigning associative arrays using compound key/value pair assignments
${THIS_SH} ./assoc11.sub
# more kvpair associative array assignment tests
${THIS_SH} ./assoc12.sub
# assignment to @ and *
${THIS_SH} ./assoc13.sub
# tests of the @k transformation on associative arrays
${THIS_SH} ./assoc14.sub
# tests with subscripts and values containing 0x01 (some indexed array tests too)
${THIS_SH} ./assoc15.sub
# tests with subscripts being expanded more than one in ${xxx} word expansions
${THIS_SH} ./assoc16.sub
# tests with `[' and `]' subscripts and `unset'
${THIS_SH} ./assoc17.sub
# tests with `[' and `]' subscripts and printf/read/wait builtins
${THIS_SH} ./assoc18.sub
+1 -1
View File
@@ -69,7 +69,7 @@ foo=(one 1 two)
declare -p foo
echo foo=\( ${foo[@]@K} \)
typeset -A a=( [\\]=bs [\"]=dquote [\)]=rparen [\]]=rbrace )
typeset -A a=( [\\]=bs [\"]=dquote [\)]=rparen [\]]=rbracket )
echo ${a[@]}
declare -p a
+74
View File
@@ -0,0 +1,74 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
foo='1 2'
bar='3 4 5'
xtra='20 40 80'
declare -A v1=( $foo 3 )
declare -p v1
declare -A v2=( [$foo]=3 )
declare -p v2
declare -A v3
v3=( $foo 3 )
declare -p v3
unset v1 v2 v3
declare -A v1=( $foo $bar )
declare -p v1
declare -A v2=( [$foo]=$bar )
declare -p v2
declare -A v3
v3=( $foo $bar )
declare -p v3
unset v1 v2 v3
declare -A v1=( "$foo" $bar )
declare -p v1
declare -A v2=( ["$foo"]=$bar )
declare -p v2
declare -A v3
v3=( "$foo" $bar )
declare -p v3
unset v1 v2 v3
declare -A v1=( "$foo" "$bar" )
declare -p v1
declare -A v2=( ["$foo"]="$bar" )
declare -p v2
declare -A v3
v3=( "$foo" "$bar" )
declare -p v3
v1+=( $xtra xtra )
v2+=( "$xtra" xtra )
v3+=( '$xtra' xtra )
declare -p v1 v2 v3
v1+=( [$xtra]='new xtra' )
v2+=( ["$xtra"]='new xtra' )
v3+=( ['$xtra']='new xtra' )
declare -p v1 v2 v3
+44
View File
@@ -0,0 +1,44 @@
# assignment to @ and *
declare -A assoc
key=@
key2=*
assoc[$key]=at
assoc[$key2]=star
assoc[!]=bang
declare -p assoc
echo ${assoc[$key]}
echo ${assoc[$key2]}
unset assoc
declare -A a
a[@]=at
declare -p a
declare -a ia
ia[@]=garbage
declare -p ia
declare a[@]=at2
declare -p a
unset a ia
declare -A a
printf -v a[@] "%10s" string
declare -p a
unset a
declare -A a
declare a[$key2]=star
declare a[@]=at
declare a[*]=star2
declare -p a
unset a
+35
View File
@@ -0,0 +1,35 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
declare -A assoc=(hello world "key with spaces" "value with spaces" one 1 foo bar)
declare -p assoc
recho "${assoc[@]}"
recho "${assoc[@]@k}"
recho "${assoc[*]}"
recho "${assoc[*]@k}"
set -- hello world "key with spaces" "value with spaces" one 1 foo bar
recho "${@}"
recho "${@@K}"
recho "${@@k}"
declare -A clone
eval clone=\( "${assoc[@]@K}" \)
declare -p clone
declare -A posparams
eval posparams=\( "${@@K}" \)
declare -p posparams
+92
View File
@@ -0,0 +1,92 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# associative arrays first
v=$'\x01'
declare -A var foo v2
var=( $'\x01' $'\x01\x01\x01\x01' )
declare -p var
v2=( $v $v$v$v$v )
declare -p v2
recho "${var[@]@k}"
eval foo=\( "${var[@]@k}" \)
declare -p foo
var=(   )
declare -p var
recho "${var[@]@k}"
eval foo=\( "${var[@]@k}" \)
declare -p foo
var=( []= )
declare -p var
recho "${var[@]@k}"
eval foo=\( "${var[@]@k}" \)
declare -p foo
# now indexed arrays
unset -v var foo
declare -a var
var=( [0]= )
declare -p var
declare -a foo
recho "${var[@]@Q}"
eval foo=\( "${var[@]@Q}" \)
declare -p foo
var=(  )
declare -p var
unset foo
declare -a foo
recho "${var[@]@Q}"
eval foo=\( "${var[@]@Q}" \)
declare -p foo
# similar to array29.sub
unset -v var foo v2
declare -A var
var=( one $'\x01\x01\x01\x01' two ab$'\001'cd )
declare -p var
pv()
{
local -A foo
eval foo=\( "${var[@]@k}" \)
declare -p foo
}
pv
pv1()
{
local -A foo=( $'\x01' "${var[two]}" )
declare -p foo
}
pv1
pv2()
{
local -A foo=( [$'\x01']="${var[one]}" )
declare -p foo
}
pv2
+56
View File
@@ -0,0 +1,56 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# bash versions up to and including bash-5.1 expanded these subscripts more
# than once
declare -A A
A["Darwin"]=darjeeling
A['$(echo Darwin ; echo stderr>&2)']=darjeeling
declare -p A
echo ${A[$(echo Darwin ; echo stderr>&2)]//eel/shark}
echo ${A['$(echo Darwin ; echo stderr>&2)']//eel/shark}
echo ${A[$(echo Darwin ; echo stderr>&2)]:0:4}
echo ${A['$(echo Darwin ; echo stderr>&2)']:0:4}
echo ${A[$(echo Darwin ; echo stderr>&2)]^^}
echo ${A['$(echo Darwin ; echo stderr>&2)']^^}
echo ${A[$(echo Darwin ; echo stderr>&2)]@Q}
echo ${A['$(echo Darwin ; echo stderr>&2)']@Q}
echo ${A[$(echo Darwin ; echo stderr>&2)]%ing}
echo ${A['$(echo Darwin ; echo stderr>&2)']%ing}
echo ${#A[$(echo Darwin ; echo stderr>&2)]}
echo ${#A['$(echo Darwin ; echo stderr>&2)']}
echo ${A[$(echo Darwin ; echo stderr>&2)]:-value}
echo ${A['$(echo Darwin ; echo stderr>&2)']:-value}
echo ${A[$(echo Darwin ; echo stderr>&2)]:+set}
echo ${A['$(echo Darwin ; echo stderr>&2)']:+set}
echo ${A[$(echo Darwin ; echo stderr>&2)]:+set}
echo ${A['$(echo Darwin ; echo stderr>&2)']:+set}
darjeeling=7*6
Darwin=7*4
echo $(( ${A[$(echo Darwin ; echo stderr>&2)]} ))
echo $(( ${A['$(echo Darwin ; echo stderr>&2)']} ))
+58
View File
@@ -0,0 +1,58 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test behavior with `unset' and `[' and ']' subscripts
declare -A A
rkey=']'
lkey='['
A[$rkey]=rbracket
A[$lkey]=lbracket
declare -p A
unset A[$rkey]
unset A[$lkey]
declare -p A
A["$rkey"]=rbracket
A["$lkey"]=lbracket
declare -p A
unset A["$rkey"]
unset A["$lkey"]
declare -p A
A[\]]=rbracket
A[\[]=lbracket
declare -p A
unset A[\]]
unset A[\[]
declare -p A
A[']']=rbracket
A['[']=lbracket
declare -p A
unset A[']']
unset A['[']
declare -p A
A["]"]=rbracket
A["["]=lbracket
declare -p A
unset A["]"]
unset A["["]
declare -p A
+59
View File
@@ -0,0 +1,59 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test behavior of builtins that can take array subscript arguments, make
# sure they work in the presence of associative arrays and `problematic' keys
# if assoc_expand_once is set
#
# affected builtins: printf, read, wait
declare -A A
rkey=']'
lkey='['
shopt -s assoc_expand_once
printf -v A[$rkey] rbracket
printf -v A[$lkey] lbracket
declare -p A
unset A[$rkey]
unset A[$lkey]
declare -p A
unset A
declare -A A
read A[$rkey] <<<rbracket
read A[$lkey] <<<lbracket
declare -p A
unset A[$rkey]
unset A[$lkey]
declare -p A
unset A
declare -A A
{ sleep 1 ; exit 4; } &
{ sleep 2 ; exit 5; } & bgpid1=$!
{ sleep 4 ; exit 6; } &
wait -p A[$rkey] -n %2 %3
case "${A[$rkey]}" in
$bgpid1) echo $?: ok 1;;
*) echo bad 1;;
esac
exit 0
+29
View File
@@ -128,3 +128,32 @@ aa[$key]=foo
echo "${aa[$key]}"
[[ -v aa[$key] ]] || echo bad assoc expansion
shopt -u assoc_expand_once
declare -A assoc
var=x123
assoc['$var']=value
declare -p assoc
unset "assoc[$var]"
declare -p assoc
unset 'assoc[$var]'
declare -p assoc
shopt -s assoc_expand_once
unset 'assoc[$var]'
declare -p assoc
typeset -A foo
foo["foo]bar"]=bip
typeset foo["foo]bar"]=bax
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
+10 -3
View File
@@ -1,3 +1,4 @@
1000
a
end-1
a
@@ -144,11 +145,11 @@ AVAR
foo
declare -x foo=""
declare -x FOO="\$\$"
./builtins.tests: line 226: declare: FOO: not found
./builtins.tests: line 228: declare: FOO: not found
declare -x FOO="\$\$"
ok
ok
./builtins.tests: line 258: kill: 4096: invalid signal specification
./builtins.tests: line 260: kill: 4096: invalid signal specification
1
a\n\n\nb
a
@@ -178,10 +179,16 @@ unset2
1
1
1
0
0
assoc A unset
array a
assoc A
array a
assoc B unset
array b unset
assoc B unset
array b unset
scalar 1
scalar 2
scalar 3 unset
@@ -271,4 +278,4 @@ type
+ command -p -- command -v type
type
+ set +x
./builtins.tests: line 282: exit: status: numeric argument required
./builtins.tests: line 284: exit: status: numeric argument required
+3 -1
View File
@@ -15,7 +15,9 @@
set +p
set +o posix
ulimit -c 0 2>/dev/null
ulimit -S -c 0 2>/dev/null
ulimit -c -S -- 1000 2>/dev/null
ulimit -c 2>/dev/null
# check that break breaks loops
for i in a b c; do echo $i; break; echo bad-$i; done
+10 -1
View File
@@ -36,15 +36,25 @@ echo ${#a[@]}
typeset -A B
typeset -a b
echo ${#B[@]}
echo ${#b[@]}
scalar1=foo
scalar2=
# this now checks for A[@] treating @ as a valid key - post-bash-5.1
if [ -v A[@] ]; then echo assoc A; else echo assoc A unset; fi
if [ -v a[@] ]; then echo array a; else echo array a unset; fi
if [ ${#A[@]} -gt 0 ]; then echo assoc A; else echo assoc A unset; fi
if [ ${#a[@]} -gt 0 ]; then echo array a; else echo array a unset; fi
if [ -v B[@] ]; then echo assoc B; else echo assoc B unset; fi
if [ -v b[@] ]; then echo array b; else echo array b unset; fi
if [ ${#B[@]} -gt 0 ]; then echo assoc B; else echo assoc B unset; fi
if [ ${#b[@]} -gt 0 ]; then echo array b; else echo array b unset; fi
if [ -v scalar1[@] ]; then echo scalar 1; else echo scalar 1 unset; fi
if [ -v scalar2[@] ]; then echo scalar 2; else echo scalar 2 unset; fi
if [ -v scalar3[@] ]; then echo scalar 3; else echo scalar 3 unset; fi
@@ -71,4 +81,3 @@ echo scalar: ${#scalar3}
echo scalar: ${#scalar3[@]}
+1
View File
@@ -14,6 +14,7 @@ no
no
no
ok
esac
ok 1
ok 2
ok 3
+4
View File
@@ -62,6 +62,10 @@ case abc in (["$empty"]|[!a-z]*) echo yes ;; (*) echo no ;; esac
case " " in ( [" "] ) echo ok;; ( * ) echo no;; esac
# posix issue discovered after bash-5.1 was released
case esac in (esac) echo esac;; esac
case k in else|done|time|esac) for f in 1 2 3 ; do :; done esac
# tests of quote removal and pattern matching
${THIS_SH} ./case1.sub
${THIS_SH} ./case2.sub
+22 -22
View File
@@ -1,41 +1,49 @@
complete -f -X '!*.+(ps|PS)' gs
complete -c nice
complete -e printenv
complete -c gdb
complete -f -X '!*.texi*' texi2html
complete -j -P '%' fg
complete -g groupmod
complete -f -X '!*.dvi' dvips
complete -f -X '!*.texi*' texi2dvi
complete -v -S '=' typeset
complete -f .
complete -c nohup
complete -a unalias
complete -g groupdel
complete -A hostname telnet
complete -v -S '=' declare
complete -v -S '=' export
complete -v -S '=' local
complete -v -S '=' readonly
complete -o bashdefault -o filenames -o nospace -F _comp_cd cd
complete -f -X '!*.dvi' xdvi
complete -c type
complete -f ln
complete -f -X '!*.+(gz|tgz)' gunzip
complete -f -X '!*.texi*' makeinfo
complete -u su
complete -j -P '%' jobs
complete -o dirnames -o filenames -o nospace -d popd
complete -A signal trap
complete -o dirnames -o filenames -o nospace -d pushd
complete -f -X '!*.pdf' acroread
complete -v unset
complete -f -X '!*.+(ps|PS)' ghostview
complete -j -W '$(ps -x | tail +2 | cut -c1-5)' -P '%' wait
complete -A hostname rsh
complete -c exec
complete -f -X '!*.Z' zmore
complete -A signal kill
complete -c eval
complete -f chown
complete -f gzip
complete -W '"${GROUPS[@]}"' newgrp
complete -A shopt shopt
complete -A hostname ftp
complete -A hostname rlogin
complete -v getopts
complete -c nice
complete -c gdb
complete -j -P '%' fg
complete -f -X '!*.dvi' dvips
complete -f -X '!*.texi*' texi2dvi
complete -f .
complete -v -S '=' declare
complete -v -S '=' export
complete -f -X '!*.dvi' xdvi
complete -u su
complete -o dirnames -o filenames -o nospace -d popd
complete -A signal trap
complete -j -W '$(ps -x | tail +2 | cut -c1-5)' -P '%' wait
complete -f -X '!*.Z' zmore
complete -j -P '%' disown
complete -f -X '!*.+(ps|PS)' gs
complete -f -X '!*.+(ps|PS)' gv
@@ -45,19 +53,11 @@ complete -A stopped -P '%' bg
complete -f cat
complete -d mkdir
complete -A helptopic help
complete -c eval
complete -f chown
complete -v read
complete -c -k time
complete -f -X '!*.Z' zcat
complete -f gzip
complete -W '"${GROUPS[@]}"' newgrp
complete -f -X '!*.Z' uncompress
complete -d rmdir
complete -A shopt shopt
complete -A hostname ftp
complete -f more
complete -A hostname rlogin
complete -v getopts
complete -f -X '!*.+(gz|tgz)' gzcat
./complete.tests: line 123: complete: notthere: no completion specification
+10 -8
View File
@@ -1,15 +1,17 @@
./comsub-eof0.sub: line 1: unexpected EOF while looking for matching `)'
./comsub-eof0.sub: line 5: syntax error: unexpected end of file
./comsub-eof0.sub: line 5: warning: here-document at line 3 delimited by end-of-file (wanted `EOF')
hi
hi
./comsub-eof2.sub: line 2: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
hi
./comsub-eof3.sub: line 1: unexpected EOF while looking for matching `)'
./comsub-eof3.sub: line 5: syntax error: unexpected end of file
./comsub-eof4.sub: line 6: warning: here-document at line 4 delimited by end-of-file (wanted `EOF')
./comsub-eof3.sub: line 4: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
./comsub-eof3.sub: line 5: unexpected EOF while looking for matching `)'
./comsub-eof4.sub: line 3: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
contents
./comsub-eof5.sub: line 8: warning: here-document at line 6 delimited by end-of-file (wanted `)')
./comsub-eof5.sub: line 4: warning: here-document at line 2 delimited by end-of-file (wanted `)')
hi
./comsub-eof5.sub: line 13: warning: here-document at line 11 delimited by end-of-file (wanted `EOF')
./comsub-eof5.sub: line 9: warning: here-document at line 7 delimited by end-of-file (wanted `EOF')
hi
./comsub-eof6.sub: line 1: unexpected EOF while looking for matching `)'
./comsub-eof5.sub: line 15: warning: here-document at line 13 delimited by end-of-file (wanted `)')
hi
./comsub-eof6.sub: command substitution: line 3: unexpected EOF while looking for matching `)'
+2
View File
@@ -1,3 +1,5 @@
# it's only the space before the paren that makes this an error
# when I fix it, it will show up here
foo=$(cat <<EOF
hi
EOF )
+6
View File
@@ -7,3 +7,9 @@ echo $(
cat <<\EOF
hi
EOF)
# this is currently an error; if I fix it it will show up here
echo "$(
cat <<\)
hi
))"
+18 -2
View File
@@ -5,11 +5,14 @@ ab
abcd
abcd
mnop
qrst
sh_352.26ax
sh_352.26ay
sh_352.25a sh_352.25b
sh_352.27 ) ) )
abc
def
here doc with )
)
bad' syntax
@@ -56,8 +59,8 @@ here-doc with \()
here-doc terminated with a parenthesis
' # or a single back- or doublequote
line terminated with a backslash
./comsub-posix1.sub: command substitution: line 2: syntax error near unexpected token `)'
./comsub-posix1.sub: command substitution: line 2: ` if x; then echo foo )'
./comsub-posix1.sub: line 1: syntax error near unexpected token `)'
./comsub-posix1.sub: line 1: `echo $( if x; then echo foo )'
after
swap32_posix is a function
swap32_posix ()
@@ -74,5 +77,18 @@ swap32_posix ()
));
done
}
./comsub-posix5.sub: line 37: syntax error near unexpected token `done'
./comsub-posix5.sub: line 37: `: $(case x in x) ;; x) done esac)'
./comsub-posix5.sub: line 38: syntax error near unexpected token `done'
./comsub-posix5.sub: line 38: `: $(case x in x) ;; x) done ;; esac)'
./comsub-posix5.sub: line 39: syntax error near unexpected token `esac'
./comsub-posix5.sub: line 39: `: $(case x in x) (esac) esac)'
bash: -c: line 1: syntax error near unexpected token `in'
bash: -c: line 1: `: $(case x in esac|in) foo;; esac)'
bash: -c: line 1: syntax error near unexpected token `done'
bash: -c: line 1: `: $(case x in x) ;; x) done)'
yes
ab cde
+26
View File
@@ -28,6 +28,11 @@ echo $(
echo $()
echo ab$()cd
echo ab$( )cd
echo mn$(
)op
echo qr$(
)st
echo $(case a in (a) echo sh_352.26ax; esac )
echo $(case a in (a) echo sh_352.26ay; esac)
@@ -42,6 +47,9 @@ echo $(
echo abc # a comment with )
)
echo $(#a comment with )
echo def)
echo $(
cat <<eof
here doc with )
@@ -231,6 +239,9 @@ ${THIS_SH} ./comsub-posix2.sub
${THIS_SH} ./comsub-posix3.sub
#${THIS_SH} ./comsub-posix4.sub
${THIS_SH} ./comsub-posix5.sub
# produced a parse error through bash-4.0-beta2
: $(echo foo)"
"
@@ -247,6 +258,12 @@ unset x
: $(case a in a) echo ;; # comment
esac)
: $(case a in
a)
echo
;; # comment
esac)
# fixed after bash-4.3 released
testing=$(
echo test | while read line; do
@@ -257,5 +274,14 @@ testing=$(
done
)
# sanity check for empty comsubs
echo $()
echo $(
)
echo $(
)
# recommended to be parsed as a nested comsub instead of arithsub
echo $(( echo ab cde ) )
+70
View File
@@ -0,0 +1,70 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
: ${THIS_SH:=./bash}
# problems with recognzing `esac' after a right paren in a command substitution
: $(case x in x) esac)
: $(case x in x) ;; x) esac)
# non-reserved word beginning with e
: $(case x in x) ;; x) echo ;; esac)
# reserved word beginning with e
: $(case x in x) ;; x) eval esac ;; esac)
: $(case x in x ) esac)
: $(case x in x ) ;; x) esac)
: $(case x in (x) esac)
: $(case x in (x) ;; (x) esac)
: $(case x in (x) ;; x) esac)
: $(case x in (x) (echo a) esac)
: $(case x in (x) (echo esac) esac)
: $(case x in x) (echo esac) esac)
# these errors should be caught sooner
: $(case x in x) ;; x) done esac)
: $(case x in x) ;; x) done ;; esac)
: $(case x in x) (esac) esac)
# these are not errors
: $(case x in x) ;; x) eval done ;; esac)
# these are just ridiculous
: $(case x in (x) a() { echo a; } esac)
: $(case x in (x) if :; then echo a; fi esac)
: $(case x in (x) { echo a; } esac)
: $(case x in (x) while false; do echo a; done esac)
: $(case x in (x) case y in (y) echo a;; esac esac)
: $(case x in (x) case y in (y) echo a;; esac ;; (y) foo ;; esac)
: $(case x in x) a() { echo a; } esac)
: $(case x in x) if :; then echo a; fi esac)
: $(case x in x) { echo a; } esac)
: $(case x in x) while false; do echo a; done esac)
: $(case x in x) case y in (y) echo a;; esac esac)
: $(case x in x) case y in (y) echo a;; esac ;; y) foo ;; esac)
: $(case x in x) case y in y) echo a;; esac ;; y) foo ;; esac)
: $(case ni in esac)
: $(case in in esac)
: $(case x in in|esac) foo;; esac)
: $(case esac in (esac) echo esac;; esac)
: $(case k in else|done|time|esac) for f in 1 2 3 ; do :; done esac)
# this is an error
${THIS_SH} -c ': $(case x in esac|in) foo;; esac)' bash
${THIS_SH} -c ': $(case x in x) ;; x) done)' bash
+9
View File
@@ -55,3 +55,12 @@ d \
g
d \
g
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
ok 8
+1
View File
@@ -73,3 +73,4 @@ ${THIS_SH} ./comsub1.sub
${THIS_SH} ./comsub2.sub
${THIS_SH} ./comsub3.sub
${THIS_SH} ./comsub4.sub
${THIS_SH} ./comsub5.sub
+43
View File
@@ -0,0 +1,43 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# this is a new feature: expanding aliases when initially parsing command
# substitutions
shopt -s expand_aliases
alias switch=case
switch foo in foo) echo ok 1;; esac
echo $( switch foo in foo) echo ok 2;; esac )
echo "$( switch foo in foo) echo ok 3;; esac )"
echo $( switch foo in (foo) echo ok 4;; esac )
echo "$( switch foo in (foo) echo ok 5;; esac )"
alias nest='('
echo $( nest echo ok 6 ) )
echo "$( nest echo ok 7 ) )"
alias short='echo ok 8 )'
echo $( short
echo "$( short "
# remember that short" won't work because you start a new quoting context
# inside $( and the token (`short') won't be delimited by the ending double
# quote, so there's no opportunity to perform the alias expansion that would
# terminate the command substitution
+7 -1
View File
@@ -2,6 +2,10 @@ returns: 0
returns: 0
returns: 1
returns: 0
1
0
1
0
returns: 0
returns: 0
returns: 0
@@ -23,10 +27,12 @@ returns: 0
returns: 1
returns: 1
returns: 0
./cond.tests: line 114: [[: 4+: syntax error: operand expected (error token is "+")
./cond.tests: line 122: [[: 4+: syntax error: operand expected (error token is "+")
returns: 1
returns: 0
returns: 0
returns: 0
returns: 0
returns: 1
returns: 0
returns: 0
+18
View File
@@ -33,6 +33,14 @@ echo returns: $?
[[ ! x || x ]]
echo returns: $?
# ! toggles on and off rather than just setting an `invert result' flag
# this differs from ksh93
[[ ! 1 -eq 1 ]]; echo $?
[[ ! ! 1 -eq 1 ]]; echo $?
[[ ! ! ! 1 -eq 1 ]]; echo $?
[[ ! ! ! ! 1 -eq 1 ]]; echo $?
# parenthesized terms didn't work right until post-2.04
[[ a ]]
echo returns: $?
@@ -122,6 +130,13 @@ A=7
[[ $IVAR -eq A ]]
echo returns: $?
[[ "$IVAR" -eq "7" ]]
echo returns: $?
A=7
[[ "$IVAR" -eq "A" ]]
echo returns: $?
unset IVAR A
# more pattern matching tests
@@ -207,6 +222,9 @@ del=$'\177'
[[ "" == "$foo" ]] && echo ok 4
[[ "$del" == "${foo,,}" ]] || echo ok 5
# allow reserved words after a conditional command just because
if [[ str ]] then [[ str ]] fi
${THIS_SH} ./cond-regexp1.sub
${THIS_SH} ./cond-regexp2.sub
+1 -1
View File
@@ -19,7 +19,7 @@ tf ()
i=$(( i + 1 ));
done;
[[ -r /dev/fd/0 && -w /dev/fd/1 ]] || echo oops > /dev/null;
for name in $( echo 1 2 3 );
for name in $(echo 1 2 3);
do
test -r /dev/fd/$name;
done;
Executable → Regular
View File
+9 -4
View File
@@ -50,15 +50,20 @@ unset before after
# EPOCHSECONDS
# not exact, but should work
# could also use python -c 'import time; ts = int(time.time()); print(ts)'
now1=$(perl -e 'print time')
# date +%s should be portable enough now
# then try gawk, perl, python in that order
now1=$(date +%s 2>/dev/null) D=date
[ -z "$now1" ] && now1=$(gawk 'BEGIN { print systime(); }' 2>/dev/null) D=gawk
[ -z "$now1" ] && now1=$(perl -e 'print time' 2>/dev/null) D=perl
[ -z "$now1" ] && now1=$(python -c 'import time; ts = int(time.time()); print(ts)' 2>/dev/null) D=python
now2=$EPOCHSECONDS
case $now1 in
$now2) echo EPOCHSECONDS ok ;;
*) echo "current time via perl and EPOCHSECONDS possible mismatch|$now1|$now2" >&2 ;;
'') echo "cannot get current time using date/gawk/perl/python" >&2 ;;
*) echo "current time via $D and EPOCHSECONDS possible mismatch|$now1|$now2" >&2 ;;
esac
unset now1 now2
unset now1 now2 D
LC_ALL=C # force decimal point to `.'
now1=$EPOCHREALTIME
+83 -81
View File
@@ -11,93 +11,95 @@ declare -fr func
unset: usage: unset [-f] [-v] [-n] [name ...]
./errors.tests: line 55: unset: func: cannot unset: readonly function
./errors.tests: line 58: declare: func: readonly function
./errors.tests: line 62: unset: XPATH: cannot unset: readonly variable
./errors.tests: line 68: unset: cannot simultaneously unset a function and a variable
./errors.tests: line 71: declare: -z: invalid option
declare: usage: declare [-aAfFgiIlnrtux] [-p] [name[=value] ...]
./errors.tests: line 73: declare: `-z': not a valid identifier
./errors.tests: line 74: declare: `/bin/sh': not a valid identifier
./errors.tests: line 78: declare: cannot use `-f' to make functions
./errors.tests: line 81: exec: -i: invalid option
./errors.tests: line 62: declare: -a: invalid option
./errors.tests: line 63: declare: -i: invalid option
./errors.tests: line 67: unset: XPATH: cannot unset: readonly variable
./errors.tests: line 73: unset: cannot simultaneously unset a function and a variable
./errors.tests: line 76: declare: -z: invalid option
declare: usage: declare [-aAfFgiIlnrtux] [name[=value] ...] or declare -p [-aAfFilnrtux] [name ...]
./errors.tests: line 78: declare: `-z': not a valid identifier
./errors.tests: line 79: declare: `/bin/sh': not a valid identifier
./errors.tests: line 83: declare: cannot use `-f' to make functions
./errors.tests: line 86: exec: -i: invalid option
exec: usage: exec [-cl] [-a name] [command [argument ...]] [redirection ...]
./errors.tests: line 85: export: XPATH: not a function
./errors.tests: line 88: break: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 89: continue: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 92: shift: label: numeric argument required
./errors.tests: line 97: shift: too many arguments
./errors.tests: line 103: let: expression expected
./errors.tests: line 106: local: can only be used in a function
./errors.tests: line 109: logout: not login shell: use `exit'
./errors.tests: line 112: hash: notthere: not found
./errors.tests: line 115: hash: -v: invalid option
./errors.tests: line 90: export: XPATH: not a function
./errors.tests: line 93: break: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 94: continue: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 97: shift: label: numeric argument required
./errors.tests: line 102: shift: too many arguments
./errors.tests: line 108: let: expression expected
./errors.tests: line 111: local: can only be used in a function
./errors.tests: line 114: logout: not login shell: use `exit'
./errors.tests: line 117: hash: notthere: not found
./errors.tests: line 120: hash: -v: invalid option
hash: usage: hash [-lr] [-p pathname] [-dt] [name ...]
./errors.tests: line 119: hash: hashing disabled
./errors.tests: line 122: export: `AA[4]': not a valid identifier
./errors.tests: line 123: readonly: `AA[4]': not a valid identifier
./errors.tests: line 126: unset: [-2]: bad array subscript
./errors.tests: line 130: AA: readonly variable
./errors.tests: line 134: AA: readonly variable
./errors.tests: line 142: shift: 5: shift count out of range
./errors.tests: line 143: shift: -2: shift count out of range
./errors.tests: line 146: shopt: no_such_option: invalid shell option name
./errors.tests: line 147: shopt: no_such_option: invalid shell option name
./errors.tests: line 150: umask: 09: octal number out of range
./errors.tests: line 151: umask: `:': invalid symbolic mode character
./errors.tests: line 152: umask: `:': invalid symbolic mode operator
./errors.tests: line 155: umask: -i: invalid option
./errors.tests: line 124: hash: hashing disabled
./errors.tests: line 127: export: `AA[4]': not a valid identifier
./errors.tests: line 128: readonly: `AA[4]': not a valid identifier
./errors.tests: line 131: unset: [-2]: bad array subscript
./errors.tests: line 135: AA: readonly variable
./errors.tests: line 139: AA: readonly variable
./errors.tests: line 147: shift: 5: shift count out of range
./errors.tests: line 148: shift: -2: shift count out of range
./errors.tests: line 151: shopt: no_such_option: invalid shell option name
./errors.tests: line 152: shopt: no_such_option: invalid shell option name
./errors.tests: line 155: umask: 09: octal number out of range
./errors.tests: line 156: umask: `:': invalid symbolic mode character
./errors.tests: line 157: umask: `:': invalid symbolic mode operator
./errors.tests: line 160: umask: -i: invalid option
umask: usage: umask [-p] [-S] [mode]
./errors.tests: line 159: umask: `u': invalid symbolic mode character
./errors.tests: line 168: VAR: readonly variable
./errors.tests: line 171: declare: VAR: readonly variable
./errors.tests: line 172: declare: VAR: readonly variable
./errors.tests: line 174: declare: unset: not found
./errors.tests: line 177: VAR: readonly variable
./errors.tests: command substitution: line 181: syntax error near unexpected token `)'
./errors.tests: command substitution: line 181: ` for z in 1 2 3; do )'
./errors.tests: command substitution: line 182: syntax error near unexpected token `done'
./errors.tests: command substitution: line 182: ` for z in 1 2 3; done )'
./errors.tests: line 184: cd: HOME not set
./errors.tests: line 185: cd: /tmp/xyz.bash: No such file or directory
./errors.tests: line 187: cd: OLDPWD not set
./errors.tests: line 188: cd: /bin/sh: Not a directory
./errors.tests: line 190: cd: /tmp/cd-notthere: No such file or directory
./errors.tests: line 193: .: filename argument required
./errors.tests: line 164: umask: `u': invalid symbolic mode character
./errors.tests: line 173: VAR: readonly variable
./errors.tests: line 176: declare: VAR: readonly variable
./errors.tests: line 177: declare: VAR: readonly variable
./errors.tests: line 179: declare: unset: not found
./errors.tests: line 182: VAR: readonly variable
./errors.tests: line 185: syntax error near unexpected token `)'
./errors.tests: line 185: `: $( for z in 1 2 3; do )'
./errors.tests: line 186: syntax error near unexpected token `done'
./errors.tests: line 186: `: $( for z in 1 2 3; done )'
./errors.tests: line 189: cd: HOME not set
./errors.tests: line 190: cd: /tmp/xyz.bash: No such file or directory
./errors.tests: line 192: cd: OLDPWD not set
./errors.tests: line 193: cd: /bin/sh: Not a directory
./errors.tests: line 195: cd: /tmp/cd-notthere: No such file or directory
./errors.tests: line 198: .: filename argument required
.: usage: . filename [arguments]
./errors.tests: line 194: source: filename argument required
./errors.tests: line 199: source: filename argument required
source: usage: source filename [arguments]
./errors.tests: line 197: .: -i: invalid option
./errors.tests: line 202: .: -i: invalid option
.: usage: . filename [arguments]
./errors.tests: line 200: set: -q: invalid option
set: usage: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
./errors.tests: line 203: enable: sh: not a shell builtin
./errors.tests: line 203: enable: bash: not a shell builtin
./errors.tests: line 206: shopt: cannot set and unset shell options simultaneously
./errors.tests: line 209: read: var: invalid timeout specification
./errors.tests: line 212: read: `/bin/sh': not a valid identifier
./errors.tests: line 215: VAR: readonly variable
./errors.tests: line 218: readonly: -x: invalid option
./errors.tests: line 205: set: -q: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 208: enable: sh: not a shell builtin
./errors.tests: line 208: enable: bash: not a shell builtin
./errors.tests: line 211: shopt: cannot set and unset shell options simultaneously
./errors.tests: line 214: read: var: invalid timeout specification
./errors.tests: line 217: read: `/bin/sh': not a valid identifier
./errors.tests: line 220: VAR: readonly variable
./errors.tests: line 223: readonly: -x: invalid option
readonly: usage: readonly [-aAf] [name[=value] ...] or readonly -p
./errors.tests: line 221: eval: -i: invalid option
./errors.tests: line 226: eval: -i: invalid option
eval: usage: eval [arg ...]
./errors.tests: line 222: command: -i: invalid option
./errors.tests: line 227: command: -i: invalid option
command: usage: command [-pVv] command [arg ...]
./errors.tests: line 225: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 226: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 229: trap: NOSIG: invalid signal specification
./errors.tests: line 232: trap: -s: invalid option
./errors.tests: line 230: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 231: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 234: trap: NOSIG: invalid signal specification
./errors.tests: line 237: trap: -s: invalid option
trap: usage: trap [-lp] [[arg] signal_spec ...]
./errors.tests: line 238: return: can only `return' from a function or sourced script
./errors.tests: line 242: break: 0: loop count out of range
./errors.tests: line 246: continue: 0: loop count out of range
./errors.tests: line 251: builtin: bash: not a shell builtin
./errors.tests: line 255: bg: no job control
./errors.tests: line 256: fg: no job control
./errors.tests: line 259: kill: -s: option requires an argument
./errors.tests: line 261: kill: S: invalid signal specification
./errors.tests: line 263: kill: `': not a pid or valid job spec
./errors.tests: line 243: return: can only `return' from a function or sourced script
./errors.tests: line 247: break: 0: loop count out of range
./errors.tests: line 251: continue: 0: loop count out of range
./errors.tests: line 256: builtin: bash: not a shell builtin
./errors.tests: line 260: bg: no job control
./errors.tests: line 261: fg: no job control
./errors.tests: line 264: kill: -s: option requires an argument
./errors.tests: line 266: kill: S: invalid signal specification
./errors.tests: line 268: kill: `': not a pid or valid job spec
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
./errors.tests: line 268: set: trackall: invalid option name
./errors.tests: line 272: xx: readonly variable
./errors.tests: line 273: set: trackall: invalid option name
./errors.tests: line 277: xx: readonly variable
1
./errors1.sub: line 14: .: -i: invalid option
.: usage: . filename [arguments]
@@ -174,14 +176,14 @@ after non-special builtin: 0
./errors7.sub: line 25: x: readonly variable
after special builtin: 0
./errors7.sub: line 27: x: readonly variable
./errors7.sub: line 29: x: readonly variable
./errors7.sub: line 21: x: readonly variable
./errors7.sub: line 21: notthere: command not found
after no such command: 127
after no such command: 1
./errors7.sub: line 23: x: readonly variable
echo builtin
after non-special builtin: 0
after non-special builtin: 1
./errors7.sub: line 25: x: readonly variable
./errors7.sub: line 27: x: readonly variable
./errors7.sub: line 29: x: readonly variable
./errors8.sub: eval: line 7: syntax error: unexpected end of file
ok 1
./errors8.sub: line 8: v: readonly variable
@@ -197,4 +199,4 @@ ok 6
bash: line 1: return: can only `return' from a function or sourced script
after return
bash: line 1: return: can only `return' from a function or sourced script
./errors.tests: line 299: `!!': not a valid identifier
./errors.tests: line 304: `!!': not a valid identifier
+5
View File
@@ -57,6 +57,11 @@ unset -f func
declare -fr func
declare -f +r func
# cannot use declare -f in combination with other attributes
a() { echo a; }
declare -f -a a
declare -f -i b c
XPATH=$PATH
declare -r XPATH
unset -v XPATH
+2
View File
@@ -26,3 +26,5 @@ echo after non-special builtin: $?
echo after special builtin: $? )
( x=8 $nocmd
echo after assignment error: $? )
( x=8
echo after assignment statement error: $? )
+11 -2
View File
@@ -20,8 +20,17 @@ after exec1.sub: one two three
126
0
this is bashenv
./exec3.sub: line 3: /tmp/bash-notthere: No such file or directory
127
trap -- 'echo EXIT' EXIT
trap -- '' SIGTERM
trap -- 'echo USR1' SIGUSR1
USR1
./exec3.sub: line 27: /tmp/bash-notthere: No such file or directory
./exec3.sub: after failed exec: 127
trap -- 'echo EXIT' EXIT
trap -- '' SIGTERM
trap -- 'echo USR1' SIGUSR1
USR1
EXIT
./execscript: line 71: notthere: No such file or directory
127
./execscript: line 74: notthere: No such file or directory
+34 -3
View File
@@ -1,6 +1,37 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test the behavior of `execfail' not exiting an interactive shell
# added tests for changes in 10/2021 for preserving the traps across a failed
# exec
shopt -s execfail
exec /tmp/bash-notthere
# make sure we're still around
echo $?
trap 'echo EXIT' EXIT
trap 'echo USR1' USR1
trap '' TERM
trap
kill -s USR1 $$ # should run the trap
exec /tmp/bash-notthere
# make sure we're still around
echo $0: after failed exec: $?
trap
kill -s USR1 $$ # should run the trap
kill -s TERM $$ # should still be ignored
# this should run the exit trap
exit 0
+12 -3
View File
@@ -227,15 +227,16 @@ argv[2] = <Y>
argv[1] = <XY^AY>
argv[1] = <x^Ay^?z>
argv[1] = <x^Ay^?z>
declare -- var="xyz"
declare -- var=$'x\001y\177z'
argv[1] = <declare>
argv[2] = <-->
argv[3] = <var="x^Ay^?z">
argv[3] = <var=$'x\001y\177z'>
var=x\001y\177z$
declare -- var="x\001y\177z"$
argv[1] = <$'x\001y\177z'>
argv[1] = <x^Ay^?z>
var=$'x\001y\177z'
./exp8.sub: line 29: xyz: syntax error: invalid arithmetic operator (error token is "z")
./exp8.sub: line 30: xyz: syntax error: invalid arithmetic operator (error token is "z")
declare -a array=()
declare -a array=([0]=$'x\001y\177z')
argv[1] = <x^Ay^?z>
@@ -408,3 +409,11 @@ cdefg
abcdefg
abcde
abcdefg
foo
declare -- a="foo"
7
declare -i a="7"
42
declare -- a="42"
FOO
declare -u A="FOO"
+1
View File
@@ -423,3 +423,4 @@ ${THIS_SH} ./exp9.sub
${THIS_SH} ./exp10.sub
${THIS_SH} ./exp11.sub
${THIS_SH} ./exp12.sub
${THIS_SH} ./exp13.sub
+34
View File
@@ -0,0 +1,34 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
unset a
echo ${a:=foo}
declare -p a
unset a
declare -i a
echo ${a:=4+3}
declare -p a
unset a
echo ${a:=42}
declare -p a
unset a
declare -u A
A=
echo ${A:=foo}
declare -p A
+2 -1
View File
@@ -19,7 +19,8 @@ recho $var
declare -p var
recho $(declare -p var)
declare -p var | sed -n l
echo "var=$var" | sed -n l
echo "declare -- var=\"$var\"" | sed -n l
recho ${var@Q}
recho ${var@P}
+1 -1
View File
@@ -4,7 +4,7 @@ exportfunc ok 2
./exportfunc.tests: eval: line 44: syntax error: unexpected end of file
./exportfunc.tests: line 43: cve7169-bad2: No such file or directory
./exportfunc1.sub: line 14: maximum here-document count exceeded
./exportfunc.tests: line 64: HELLO_WORLD: No such file or directory
./exportfunc.tests: line 72: HELLO_WORLD: No such file or directory
eval ok
./exportfunc3.sub: line 23: export: foo=bar: cannot export
status: 1
+9 -1
View File
@@ -50,10 +50,18 @@ ${THIS_SH} ./exportfunc1.sub
${THIS_SH} ./exportfunc2.sub
# CVE-2014-6277
A100=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
A1000=${A100}
for (( i = 0; i < 999; i++ ))
do
A1000+=${A100}
done
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<0 0" ${THIS_SH} -c foo 2>/dev/null
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<`perl -e '{print "A"x100000}'` 0" ${THIS_SH} -c foo 2>/dev/null
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<${A1000} 0" ${THIS_SH} -c foo 2>/dev/null
${THIS_SH} -c "f(){ x(){ _;}; x(){ _;}<<a;}" 2>/dev/null
unset A100 A1000
# CVE-2014-6278
+72 -4
View File
@@ -92,16 +92,16 @@ a ab
a ab
a ab
a
. ..
. .. a.log
*(.)
a.log
*(foo)
*(foo|bar)
a.log
?(foo)
a.log
a.log
. ..
. ..
*(foo).*
*(foo|bar).*
a.log
a.log
.x .y .z
@@ -114,3 +114,71 @@ a b c
.x .y .z a b c
.x .y .z a b c
*
.b a
.b a
a .b
.b
.b
.b a
.b a
a .b
.b
.b
dotglob: .a .foo bar
@(.foo)
.foo
!(.foo)
.a bar
@(.foo|*)
.a .foo bar
!(.foo|*)
!(.foo|*)
@(*)
.a .foo bar
!(*)
!(*)
.*
. .. .a .foo
@(.*)
. .. .a .foo
!(.*)
bar
no dotglob: .a .foo bar
@(.foo)
.foo
!(.foo)
bar
@(.foo|*)
.foo bar
!(.foo|*)
!(.foo|*)
!(bar).foo
!(bar).foo
*(bar).foo
.foo
?(bar).foo
.foo
.?
.. .a
@(.?)
.. .a
!(.?)
bar
dotglob: .a .foo bar
@(?|.?)
.. .a
@(?|.*)
. .. .a .foo
? .*
? . .. .a .foo
*
.a .foo bar
no dotglob: .a .foo bar
@(?|.?)
.. .a
@(?|.*)
. .. .a .foo
? .*
? . .. .a .foo
*
bar
+2 -4
View File
@@ -380,13 +380,11 @@ shopt -u globstar
builtin cd "$MYDIR"
${THIS_SH} ./extglob1.sub
${THIS_SH} ./extglob1a.sub
${THIS_SH} ./extglob3.sub
${THIS_SH} ./extglob4.sub
${THIS_SH} ./extglob5.sub
${THIS_SH} ./extglob6.sub
${THIS_SH} ./extglob7.sub
exit 0
+25 -1
View File
@@ -2,6 +2,30 @@ LANG=en_US.UTF-8
shopt -s extglob
a="aaaäöü"
a1=${a:3:3}
[[ "${a}" == "${a1}" ]] || {
echo cond ok 1
}
case "${a//?aa}" in
"${a1}") echo ok 1;;
*) echo bad 1;;
esac
case "${a//\aaa}" in
"${a1}") echo ok 2;;
*) echo bad 2;;
esac
case "${a//aaa}" in
"${a1}") echo ok 3;;
*) echo bad 3;;
esac
case "${a//@(?aa)}" in
"${a1}") echo ok 4;;
*) echo bad 4;;
esac
echo "${a}" "${a//?aa}" "${a//\aaa}"
exit 0
+43
View File
@@ -0,0 +1,43 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# issues with ? matching "." in certain special circumstances with dotglob set
shopt -s dotglob extglob
DIR=$TMPDIR/extglob-$$
mkdir $DIR
cd $DIR
touch a .b
LC_COLLATE=C # fix sort order
echo @(?|.?)
echo @(.?|?)
echo ? .?
echo .*
echo \.*
shopt -u dotglob
echo @(?|.?)
echo @(.?|?)
echo ? .?
echo .*
echo \.*
cd $OLDPWD
rm -rf $DIR
+97
View File
@@ -0,0 +1,97 @@
: ${TMPDIR:=/tmp}
TESTDIR=$TMPDIR/glob-test-$$
mkdir $TESTDIR || {
echo "$TESTDIR: cannot create" >&2
exit 1
}
cd $TESTDIR || {
echo "$TESTDIR: cannot cd" >&2
exit 1
}
LC_CTYPE=C LC_COLLATE=C
shopt -s extglob dotglob
shopt -u globskipdots # XXX - backwards compatibility
touch .foo bar .a
echo dotglob: .a .foo bar
echo '@(.foo)'
echo @(.foo)
echo '!(.foo)'
echo !(.foo)
echo '@(.foo|*)'
echo @(.foo|*)
echo '!(.foo|*)'
echo !(.foo|*)
echo '@(*)'
echo @(*)
echo '!(*)'
echo !(*)
echo '.*'
echo .*
echo '@(.*)'
echo @(.*)
echo '!(.*)'
echo !(.*)
shopt -u dotglob
echo no dotglob: .a .foo bar
echo '@(.foo)'
echo @(.foo)
echo '!(.foo)'
echo !(.foo)
echo '@(.foo|*)'
echo @(.foo|*)
echo '!(.foo|*)'
echo !(.foo|*)
echo '!(bar).foo'
echo !(bar).foo
echo '*(bar).foo'
echo *(bar).foo
echo '?(bar).foo'
echo ?(bar).foo
echo '.?'
echo .?
echo '@(.?)'
echo @(.?)
echo '!(.?)'
echo !(.?)
shopt -s dotglob
echo dotglob: .a .foo bar
echo '@(?|.?)'
echo @(?|.?)
echo '@(?|.*)'
echo @(?|.*)
echo '? .*'
echo ? .*
echo '*'
echo *
shopt -u dotglob
echo no dotglob: .a .foo bar
echo '@(?|.?)'
echo @(?|.?)
echo '@(?|.*)'
echo @(?|.*)
echo '? .*'
echo ? .*
echo '*'
echo *
rm -f .a bar .foo
cd $OLDPWD
rm -rf $TESTDIR
+6
View File
@@ -11,6 +11,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# since we look at functions below, remove all functions now
funcs=$(compgen -A function)
if [ -n "$funcs" ]; then
unset -f $funcs
fi
a()
{
x=$((x - 1))
+2 -2
View File
@@ -15,10 +15,10 @@ set -- -a bb
readonly OPTARG
getopts :x x
echo OPTARG = $OPTARG x = $x
echo OPTARG = $OPTARG x = "$x"
getopts x x
echo ${OPTARG-unset} x = $x
echo ${OPTARG-unset} x = "$x"
typeset -r RO=foo
typeset -n OPTARG=RO
+5 -1
View File
@@ -121,6 +121,10 @@ a\*b
a\*b*
é/*
é/*
a aa b bb
.a .aa .b .bb a aa b bb
.a .aa .b .bb
. .. .a .aa .b .bb
argv[1] = <a>
argv[2] = <abc>
argv[3] = <abd>
@@ -135,7 +139,7 @@ argv[2] = <abc>
argv[3] = <abd>
argv[4] = <abe>
tmp/l1 tmp/l2 tmp/*4 tmp/l3
./glob.tests: line 65: no match: tmp/*4
./glob.tests: line 66: no match: tmp/*4
argv[1] = <bdir/>
argv[1] = <*>
argv[1] = <a*>
+1
View File
@@ -30,6 +30,7 @@ ${THIS_SH} ./glob6.sub
${THIS_SH} ./glob7.sub
${THIS_SH} ./glob8.sub
${THIS_SH} ./glob9.sub
${THIS_SH} ./glob10.sub
MYDIR=$PWD # save where we are
+32
View File
@@ -0,0 +1,32 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test basic behavior of globskipdots
TDIR=/tmp/dotglob-$$
{ mkdir $TDIR && cd $TDIR; } || exit 1
touch a b aa bb .a .b .aa .bb
echo *
shopt -s dotglob
echo *
shopt -s globskipdots
echo .*
shopt -u globskipdots
echo .*
cd $OLDPWD
rm -rf $TDIR
+2
View File
@@ -11,6 +11,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[ $UID -eq 0 ] && { echo "glob5.sub: the test suite should not be run as root" >&2 ; }
ORIGD=$PWD
: ${TMPDIR:=/var/tmp}
+1
View File
@@ -12,6 +12,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# tests of the backslash-in-glob-patterns discussion on the austin-group ML
[ $UID -eq 0 ] && { echo "glob6.sub: the test suite should not be run as root" >&2 ; }
: ${TMPDIR:=/var/tmp}
+31 -5
View File
@@ -67,13 +67,13 @@ qux
bar
qux
abc def geh
./heredoc3.sub: line 23: warning: here-document at line 21 delimited by end-of-file (wanted `EOF')
./heredoc3.sub: line 20: warning: here-document at line 18 delimited by end-of-file (wanted `EOF')
= here is the text =
./heredoc3.sub: line 29: warning: here-document at line 27 delimited by end-of-file (wanted `EOF')
./heredoc3.sub: line 26: warning: here-document at line 24 delimited by end-of-file (wanted `EOF')
this paren ) is not a problem
./heredoc3.sub: line 35: warning: here-document at line 33 delimited by end-of-file (wanted `EOF')
./heredoc3.sub: line 32: warning: here-document at line 30 delimited by end-of-file (wanted `EOF')
these balanced parens ( ) are not a problem
./heredoc3.sub: line 41: warning: here-document at line 39 delimited by end-of-file (wanted `EOF')
./heredoc3.sub: line 38: warning: here-document at line 36 delimited by end-of-file (wanted `EOF')
quoted balanced parens \( ) are not a problem either
more text in a subshell
some more text in a different subshell
@@ -100,7 +100,33 @@ argv[2] = <threefour>
argv[1] = <two>
argv[2] = <threefi>
argv[3] = <ve>
1: OK
2: OK
3: OK
4: OK
5: OK
6: OK
7: OK
1: OK
2: OK
3: OK
4: OK
5: OK
5: OK
1: ${x#$'no\t'}
2: O${x#$'no\t'O}
3: ${x#n$'o\t'}
4: ${x#'no '}
5: ${x#$pat}
6: ${y#$'not'}
7: ${y#'not'}
foo bar
./heredoc7.sub: line 21: after: command not found
./heredoc7.sub: line 29: warning: here-document at line 29 delimited by end-of-file (wanted `EOF')
./heredoc7.sub: line 29: foobar: command not found
./heredoc7.sub: line 29: EOF: command not found
grep: *.c: No such file or directory
comsub here-string
./heredoc.tests: line 149: warning: here-document at line 147 delimited by end-of-file (wanted `EOF')
./heredoc.tests: line 156: warning: here-document at line 154 delimited by end-of-file (wanted `EOF')
hi
there
+7
View File
@@ -137,6 +137,13 @@ ${THIS_SH} ./heredoc4.sub
# heredoc tests that use different size documents to test pipe implementation
${THIS_SH} ./heredoc5.sub
# test $'...' and $"..." quoted strings in here-documents
${THIS_SH} ./heredoc6.sub
# interaction between here-documents and command substitutions
${THIS_SH} ./heredoc7.sub
echo $(
cat <<< "comsub here-string"
)
+50
View File
@@ -0,0 +1,50 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test $'...' and $"..." strings in here documents (problem through bash-5.1)
pat=$'no\t'
x=$'no\tOK'
y=notOK
cat <<EOF
1: ${x#$'no\t'}
2: O${x#$'no\t'O}
3: ${x#n$'o\t'}
4: ${x#'no '}
5: ${x#$pat}
6: ${y#$'not'}
7: ${y#'not'}
EOF
cat <<EOF
1: ${x#$"no "}
2: ${x#n$"o "}
3: O${x#n$"o "O}
4: ${x#"no "}
5: ${y#$"not"}
5: ${y#"not"}
EOF
# we don't perform dollar-quote expansion if the here-doc delimiter is quoted
cat <<\EOF
1: ${x#$'no\t'}
2: O${x#$'no\t'O}
3: ${x#n$'o\t'}
4: ${x#'no '}
5: ${x#$pat}
6: ${y#$'not'}
7: ${y#'not'}
EOF
+29
View File
@@ -0,0 +1,29 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# should characters outside a command substitution be interpreted as a delimiter
# for a here-document started inside it?
echo $(cat << EOF)
foo
bar
EOF
after
# should characters inside a command substitution be interpreted as a delimiter
# for a here-document started outside of it?
cat <<EOF && grep $(
foobar
EOF
echo notthereanywhere) *.c
+6
View File
@@ -11,6 +11,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# since we look at functions below, remove all functions now
funcs=$(compgen -A function)
if [ -n "$funcs" ]; then
unset -f $funcs
fi
# basics
read x <<<"alpha"
echo "$x"
+35 -2
View File
@@ -140,9 +140,9 @@ three
one
two
three
5.1
5.2
echo ${BASH_VERSION%\.*}
5.1
5.2
echo ${BASH_VERSION%\.*}
a
b
@@ -264,3 +264,36 @@ out of range 3
12 echo out of range 3
out of range 4
13 fc -l 1 99
1
2
3
4
5
6
3 echo 3
4 echo 4
5 echo 5
6 echo 6
3 echo 3
4 echo 4
5 echo 5
6
7
4 echo 4
5 echo 5
6 echo 6
7 echo 7
4 echo 4
5 echo 5
6 echo 6
7
8
5 echo 5
6 echo 6
9
10
5 echo 5
6 echo 6
7 echo 9
8 echo 10
5 echo 10
+1
View File
@@ -130,3 +130,4 @@ ${THIS_SH} ./history2.sub
${THIS_SH} ./history3.sub
${THIS_SH} ./history4.sub
${THIS_SH} ./history5.sub
${THIS_SH} ./history6.sub
+55
View File
@@ -0,0 +1,55 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
: ${TMPDIR:=/tmp}
HISTFILE=${TMPDIR}/history-$$
HISTSIZE=4
HISTIGNORE="history*"
set -o history
history -c
echo 1
echo 2
echo 3
echo 4
echo 5
echo 6
history
history -d -1
history
echo 6
echo 7
history
history -d -1
history
echo 7
echo 8
history -d -2--1
history
echo 9
echo 10
history
history -d 5-7
history
unset HISTFILE
exit 0
+1
View File
@@ -31,6 +31,7 @@ i killed it
./jobs5.sub: line 40: wait: %8: no such job
2: ok 2
2: ok 3
127
child1 exit status 0
[1]+ Running sleep 20 &
./jobs7.sub: line 5: fg: no current jobs
+2
View File
@@ -34,4 +34,6 @@ wait
# the sleep is intended to give the kill time to execute before the job
# exits
(sleep 1 ; cat ) &
# suppress any message about terminated process
exec 2>/dev/null
kill -1 %% && echo i killed it || echo could not kill it
+5
View File
@@ -59,3 +59,8 @@ disown -a
unset bgpid1 bgpid2 bgpid3
unset wpid
# now that we have no jobs, make sure that wait -n -p var leaves var unset
jobs
wait -n -p wpid
echo $wpid $?
+2
View File
@@ -3,4 +3,6 @@ set -m
sleep 20 &
echo $(jobs)
echo $(fg %% ; jobs)
# suppress any message about sleep 20 being terminated
exec 2>/dev/null
kill %1
+2
View File
@@ -18,3 +18,5 @@ A2
B1
B2
HI -- 42 -- 0 42
x=x
x=x
+1
View File
@@ -71,3 +71,4 @@ ${THIS_SH} ./lastpipe1.sub
echo lastpipe1.sub returns $?
${THIS_SH} ./lastpipe2.sub
${THIS_SH} ./lastpipe3.sub
+11
View File
@@ -0,0 +1,11 @@
# problem in bash-5.1 running lastpipe in subshell if fd 0 is closed
shopt -s lastpipe
exec 0<&-
echo x | read x
echo x=$x
unset x
echo x | cat | read x
echo x=$x
+1
View File
@@ -151,6 +151,7 @@ a
[27] aaa
[28] aaa
[29] aaa
declare -a array=([0]="a" [1]="b" [2]="c" [3]=$'\n')
1 2 3 4 5
foo 0 1
+6 -1
View File
@@ -52,6 +52,11 @@ for (( i = 0 ; i < ${#E[@]} ; i++ )); do
echo "${E[${i}]}"
done
${THIS_SH} ./mapfile1.sub
unset -v s array
s=$'a\xffb\xffc\xff'
mapfile -t -d $'\xff' array <<<"$s"
declare -p array
unset -v s array
${THIS_SH} ./mapfile1.sub
${THIS_SH} ./mapfile2.sub
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
+75
View File
@@ -348,6 +348,10 @@ declare -a v=([1]="1")
declare -a v=([0]="0" [1]="1")
declare -n n="v[1]"
declare -a v=([0]="0")
./nameref15.sub: line 120: warning: xref: removing nameref attribute
declare -a xref=([1]="one")
./nameref15.sub: line 126: warning: xref: removing nameref attribute
declare -a xref=([1]="one")
declare -n r1="y"
declare -n r2="x"
./nameref16.sub: line 25: typeset: x: not found
@@ -424,6 +428,23 @@ declare -a var=([123]="")
declare -n ref="var[123]"
./nameref18.sub: line 67: declare: var[123]: not found
declare -a var=([123]="X")
argv[1] = <1>
argv[2] = <2>
argv[3] = <3>
argv[1] = <1>
argv[2] = <2>
argv[3] = <3>
argv[1] = <1>
argv[2] = <2>
argv[3] = <3>
argv[1] = <1>
argv[2] = <2>
argv[3] = <3>
argv[1] = <1>
argv[2] = <2>
argv[3] = <31>
argv[4] = <2>
argv[5] = <3>
declare -n foo="bar"
declare -- foo="bar"
./nameref19.sub: line 22: declare: bar: not found
@@ -440,6 +461,8 @@ declare -n foo="bar"
declare -- bar
declare -- foo="bar"
declare -- bar
8
declare -n ivar="foo"
declare -a v=([0]="Y")
r: <Y>
v: <Y>
@@ -483,3 +506,55 @@ declare -n ref="var"
declare -ai var=([1]="0")
declare -n ref="var"
declare -- var="1"
a string with spaces
many spaces
declare -n foo="bar[0]"
declare -a bar=([0]=" still more spaces")
declare -n foo="bar[0]"
declare -a bar=([0]="spaces still more spaces")
./nameref22.sub: line 50: declare: array: reference variable cannot be an array
./nameref22.sub: line 53: declare: array[128]: reference variable cannot be an array
declare -a array=([0]="one" [1]="two" [2]="three")
declare -- array="(one two three)"
declare -a array=([0]="one" [1]="two" [2]="three")
./nameref22.sub: line 69: declare: `(one two three)': invalid variable name for name reference
./nameref22.sub: line 70: declare: array: reference variable cannot be an array
declare -a array=([0]="zero")
./nameref22.sub: line 74: declare: array: reference variable cannot be an array
declare -a array=([0]="one" [1]="two" [2]="three")
./nameref22.sub: line 79: declare: array: reference variable cannot be an array
declare -a array
declare -ai array=([0]="one")
declare -a array=([0]="zero")
declare -a array=([0]="one" [1]="two" [2]="three")
declare -ai a=([0]="5")
declare -ai a=([0]="6")
declare -ai a=([0]="1")
./nameref23.sub: line 15: declare: b: not found
declare -ai a=([0]="1")
declare -- b="1"
declare -ai a=([0]="1")
declare -- b="11"
declare -ai a=([0]="1")
declare -- b="110"
./nameref23.sub: line 25: declare: `1': invalid variable name for name reference
declare -ai a=([0]="1")
./nameref23.sub: line 27: declare: b: not found
declare -ai a=([0]="4")
declare -in b="a[0]"
declare -ai a=([0]="6")
declare -in b="a[0]"
foo
foo bar
declare -a a=([0]="" [1]="foo bar")
declare -n b="a[1]"
foo
foo bar
declare -a a=([0]="" [1]="foo bar")
declare -n b="a[1]"
12
16
declare -ai a=([0]="0" [1]="16")
12
16
declare -ai a=([0]="0" [1]="16")
+10
View File
@@ -115,3 +115,13 @@ v=(0 1)
declare -n n=v[1]
unset n
declare -p n v
declare -n xref
declare -a xref[1]=one
declare -p xref
unset xref
declare -n xref
xref=array
declare -a xref[1]=one
declare -p xref
+16
View File
@@ -65,3 +65,19 @@ declare -p ref ${!ref} var
declare +t ref
ref=X
declare -p ref ${!ref} var
unset -n ref
unset var
arr=(1 2 3)
indir='arr[@]'
declare -n ref='arr[@]'
recho "${!indir}"
recho ${!indir}
recho "$ref"
recho $ref
recho "${!indir}$ref"
+9
View File
@@ -62,3 +62,12 @@ declare bar
declare -p foo bar
declare +n foo
declare -p foo bar
# but when we add the nameref attribute, we remove other attributes
declare -i ivar
ivar=4+4
echo $ivar
declare -n ivar=foo
declare -p ivar
+97
View File
@@ -0,0 +1,97 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
declare -n foo=bar
declare foo='a string with spaces'
echo $foo
unset foo
declare foo+='many spaces'
echo $foo
unset foo # unsets bar
unset -n foo
declare -a bar
declare -n foo='bar[0]'
declare foo+=' still more spaces'
declare -p foo bar
unset -n foo
unset bar
declare -a bar
declare -n foo='bar[0]'
declare foo=spaces
declare foo+=' still more spaces'
declare -p foo bar
unset -n foo
unset bar
ray=ray
declare -a array
array[0]=zero
declare -n array
unset array
declare -n array[128]
unset array
declare -a array='(one two three)'
declare -p array
unset array
declare array='(one two three)'
declare -p array
unset array
declare -a ar$ray='(one two three)'
declare -p ar$ray
unset array
declare -a array=(zero)
declare -n array='(one two three)'
declare -n array=three
declare -p array
unset array
declare -n array=(one two three)
declare -p array
unset array
declare -a array
declare -n array=one
declare -p array
unset array
array=one
declare -i array[64];
declare -p array
unset array
declare -a array=zero
declare -p array
unset array
declare -a array
declare array='(one two three)'
declare -p array
unset array
+82
View File
@@ -0,0 +1,82 @@
declare -ai a
a[0]=4
declare -n b='a[0]'
b+=1 ; declare -p a
declare b+=1 ; declare -p a
unset a b
unset -n b
######
declare -ai a=(1)
declare -in b="a[0]"
declare -p a b
b+=1 ; declare -p a b
b+=1 ; declare -p a b
b+=0 ; declare -p a b
unset a b
#####
declare -ai a=(1)
declare -n b="1"
declare -p a
declare -np b
unset a ; unset -n b
#####
declare -ai a=('4');
declare -n b='a[0]';
declare -ni b; # this should maybe not be allowed, but it is for now
declare -p a b
b+=2;
declare -p a b
unset a ; unset -n b
#####
f()
{
local -a a=('' 'foo');
local -n b=a[1];
echo $b;
b+=\ bar;
echo $b;
declare -p a b;
}
f
declare -a a=('' 'foo');
declare -n b=a[1];
echo $b;
b+=\ bar;
echo $b;
declare -p a b
unset a ; unset -n b
unset -f f
f()
{
local -ai a=(0 12);
local -n b=a[1];
echo $b;
b+=4;
echo $b;
declare -p a;
}
f
declare -ai a=(0 12);
declare -n b=a[1];
echo $b;
b+=4;
echo $b;
declare -p a
unset a ; unset -n b
+42 -2
View File
@@ -617,7 +617,7 @@ c Sub = 0 2 4 8
<>
<>
<'ab '\''cd'\'' ef'>
./new-exp10.sub: line 24: ${x@C}: bad substitution
bash: line 1: ${x@C}: bad substitution
<'ab'> <'cd ef'> <''> <'gh'>
<'ab' 'cd ef' '' 'gh'>
<'ab'> <'cd> <ef'> <''> <'gh'>
@@ -625,7 +625,7 @@ c Sub = 0 2 4 8
<'ab cd'>
<'4'> <'ab cd'>
<>
argv[1] = <host(2)[5.1]$ >
argv[1] = <host(2)[5.2]$ >
<
>
<' \t\n'>
@@ -703,11 +703,21 @@ aaa bbb
a bbb
aaa bb
'string'
'string'
'value with spaces'
'value with spaces'
'a b' 'c d' 'e f'
'a b' 'c d' 'e f'
0 "zero" 1 "one" 2 "two" 3 "three"
0 "zero z" 1 "one o" 2 "two t" 3 "three t"
argv[1] = <0>
argv[2] = <zero z>
argv[3] = <1>
argv[4] = <one o>
argv[5] = <2>
argv[6] = <two t>
argv[7] = <3>
argv[8] = <three t>
declare -a foo=()
ai
declare -ai foo
@@ -719,6 +729,36 @@ a
a
a
a
/homes/chetdefg
/homes/chetdefg
~defg
defg
defg
defg
$'a' $'b' $'c' $'d' $'e' $'f' $'g'
a b c d e f g
a b c d e f g
a b c d e f g
& & & & & & &
a a a a a a a
3 3 3 3 3 3 3
abc defg
abc defg
abc defg
abc defg
abc defg
& defg
& defg
abcdefg
abcdefg
&defg
&defg
\abcdefg
&defg
&defg
\&defg
\&defg
\\&defg
argv[1] = </>
argv[1] = </>
+4
View File
@@ -631,6 +631,10 @@ ${THIS_SH} ./new-exp14.sub
# ongoing work with a/A parameter transformations and `nounset'
${THIS_SH} ./new-exp15.sub
# pattern substitution with `&' (quoted and unquoted) in the replacement string
${THIS_SH} ./new-exp16.sub
# problems with stray CTLNUL in bash-4.0-alpha
unset a
a=/a
+3 -1
View File
@@ -21,7 +21,9 @@ printf "<%s>" "${x@A}" ; echo
x="ab 'cd' ef"
printf "<%s> " "${x@Q}" ; echo
printf "<%s>" "${x@C}"
# this needs to be run in a subshell because invalid transformation operators
# are now treated as substitution errors, fatal in non-interactive shells
${THIS_SH} -c 'x=abcdef ; printf "<%s>" "${x@C}"' bash
# if unquoted, normal word splitting happens
set -- ab 'cd ef' '' gh
+18 -1
View File
@@ -1,4 +1,18 @@
# test the other uses of the 'K' tranform operator
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test the other uses of the 'K' tranform operator and its sibling 'k'
# the associative array tests are performed separately, since that was the
# original motivation for this feature
foo=string
@@ -7,7 +21,9 @@ bar='value with spaces'
set -- 'a b' 'c d' 'e f'
echo ${foo@K}
echo ${foo@k}
echo ${bar@K}
echo ${bar@k}
echo ${@@K}
echo "${@@K}"
@@ -17,3 +33,4 @@ echo ${foo[@]@K}
foo=( 'zero z' 'one o' 'two t' 'three t' )
echo ${foo[@]@K}
recho "${foo[@]@k}"
+63
View File
@@ -0,0 +1,63 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
HOME=/homes/chet
string=abcdefg
set -- a b c
# verify existing behavior
echo ${string/abc/~}
echo "${string/abc/~}"
echo ${string/abc/"~"}
echo ${string/abc/$notthere}
echo "${string/abc/$notthere}"
echo "${string/abc/"$notthere"}"
echo ${string//?/\$\'&\' }
shopt -s patsub_replacement
echo ${string//?/\& }
echo "${string//?/\& }"
echo ${string//?/"& "}
echo ${string//?/"\& "}
echo "${string//?/"a "}"
echo "${string//?/"$# "}"
echo ${string/abc/& }
echo "${string/abc/& }"
echo ${string/abc/"& "}
echo ${string/abc/\& }
echo "${string/abc/\& }"
echo ${string/abc/"\& "}
echo ${string/abc/\\& }
rep='\\&'
echo "${string/abc/&}"
echo ${string/abc/\&}
echo "${string/abc/\\&}"
echo "${string/abc/"\\&"}"
echo ${string/abc/"$rep"}
shopt -u patsub_replacement
echo "${string/abc/&}"
echo ${string/abc/\&}
echo "${string/abc/\\&}"
echo "${string/abc/"\\&"}"
echo ${string/abc/"$rep"}
+6
View File
@@ -35,6 +35,10 @@ argv[1] = <hello, $world>
;foo
argv[1] = <^I>
argv[1] = <'A^IB'>
argv[1] = <a^Ib^Ic>
argv[1] = <$'a\tb\tc'>
AD
E
hello' world
hello world!
hello' world!
@@ -62,3 +66,5 @@ argv[1] = <^?>
0000000 esc fs gs rs us del nl
0000007
\q
foo
./nquote4.sub: line 6: quux: command not found
+8
View File
@@ -128,6 +128,14 @@ unset mytab
recho "${mytab:-$'\t'}"
recho "$( args $'A\tB' )"
# tests for $'...' not being expanded when inside double quotes
recho $'a\tb\tc'
recho "$'a\tb\tc'"
# tests for $'...' being expanded in command substitution, and when
echo "$(echo $'\t\t\101\104\n\105')"
${THIS_SH} ./nquote1.sub
${THIS_SH} ./nquote2.sub
${THIS_SH} ./nquote3.sub
${THIS_SH} ./nquote4.sub

Some files were not shown because too many files have changed in this diff Show More