| 1 | # this is needed so that the bad assignments (b[]=bcde, for example) do not
|
|---|
| 2 | # cause fatal shell errors when in posix mode
|
|---|
| 3 | set +o posix
|
|---|
| 4 |
|
|---|
| 5 | set +a
|
|---|
| 6 | # The calls to egrep -v are to filter out builtin array variables that are
|
|---|
| 7 | # automatically set and possibly contain values that vary.
|
|---|
| 8 |
|
|---|
| 9 | # first make sure we handle the basics
|
|---|
| 10 | x=()
|
|---|
| 11 | echo ${x[@]}
|
|---|
| 12 | unset x
|
|---|
| 13 |
|
|---|
| 14 | # this should be an error
|
|---|
| 15 | test=(first & second)
|
|---|
| 16 | echo $?
|
|---|
| 17 | unset test
|
|---|
| 18 |
|
|---|
| 19 | # make sure declare -a converts an existing variable to an array
|
|---|
| 20 | unset a
|
|---|
| 21 | a=abcde
|
|---|
| 22 | declare -a a
|
|---|
| 23 | echo ${a[0]}
|
|---|
| 24 |
|
|---|
| 25 | unset a
|
|---|
| 26 | a=abcde
|
|---|
| 27 | a[2]=bdef
|
|---|
| 28 |
|
|---|
| 29 | unset b
|
|---|
| 30 | declare -a b[256]
|
|---|
| 31 |
|
|---|
| 32 | unset c[2]
|
|---|
| 33 | unset c[*]
|
|---|
| 34 |
|
|---|
| 35 | a[1]=
|
|---|
| 36 |
|
|---|
| 37 | _ENV=/bin/true
|
|---|
| 38 | x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
|
|---|
| 39 |
|
|---|
| 40 | declare -r c[100]
|
|---|
| 41 |
|
|---|
| 42 | echo ${a[0]} ${a[4]}
|
|---|
| 43 | echo ${a[@]}
|
|---|
| 44 |
|
|---|
| 45 | echo ${a[*]}
|
|---|
| 46 |
|
|---|
| 47 | # this should print out values, too
|
|---|
| 48 | declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
|
|---|
| 49 |
|
|---|
| 50 | unset a[7]
|
|---|
| 51 | echo ${a[*]}
|
|---|
| 52 |
|
|---|
| 53 | unset a[4]
|
|---|
| 54 | echo ${a[*]}
|
|---|
| 55 |
|
|---|
| 56 | echo ${a}
|
|---|
| 57 | echo "${a}"
|
|---|
| 58 | echo $a
|
|---|
| 59 |
|
|---|
| 60 | unset a[0]
|
|---|
| 61 | echo ${a}
|
|---|
| 62 |
|
|---|
| 63 | echo ${a[@]}
|
|---|
| 64 |
|
|---|
| 65 | a[5]="hello world"
|
|---|
| 66 | echo ${a[5]}
|
|---|
| 67 | echo ${#a[5]}
|
|---|
| 68 |
|
|---|
| 69 | echo ${#a[@]}
|
|---|
| 70 |
|
|---|
| 71 | a[4+5/2]="test expression"
|
|---|
| 72 | echo ${a[@]}
|
|---|
| 73 |
|
|---|
| 74 | readonly a[5]
|
|---|
| 75 | readonly a
|
|---|
| 76 | # these two lines should output `declare' commands
|
|---|
| 77 | readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
|
|---|
| 78 | declare -ar | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
|
|---|
| 79 | # this line should output `readonly' commands, even for arrays
|
|---|
| 80 | set -o posix
|
|---|
| 81 | readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
|
|---|
| 82 | set +o posix
|
|---|
| 83 |
|
|---|
| 84 | declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")'
|
|---|
| 85 | d[9]="ninth element"
|
|---|
| 86 |
|
|---|
| 87 | declare -a e[10]=test # this works in post-bash-2.05 versions
|
|---|
| 88 | declare -a e[10]='(test)'
|
|---|
| 89 |
|
|---|
| 90 | pass=/etc/passwd
|
|---|
| 91 | declare -a f='("${d[@]}")'
|
|---|
| 92 | b=([0]=this [1]=is [2]=a [3]=test [4]="$PS1" [5]=$pass)
|
|---|
| 93 |
|
|---|
| 94 | echo ${b[@]:2:3}
|
|---|
| 95 |
|
|---|
| 96 | declare -pa | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
|
|---|
| 97 |
|
|---|
| 98 | a[3]="this is a test"
|
|---|
| 99 |
|
|---|
| 100 | b[]=bcde
|
|---|
| 101 | b[*]=aaa
|
|---|
| 102 | echo ${b[ ]}
|
|---|
| 103 |
|
|---|
| 104 | c[-2]=4
|
|---|
| 105 | echo ${c[-4]}
|
|---|
| 106 |
|
|---|
| 107 | d[7]=(abdedfegeee)
|
|---|
| 108 |
|
|---|
| 109 | d=([]=abcde [1]="test test" [*]=last [-65]=negative )
|
|---|
| 110 |
|
|---|
| 111 | unset d[12]
|
|---|
| 112 | unset e[*]
|
|---|
| 113 |
|
|---|
| 114 | declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
|
|---|
| 115 |
|
|---|
| 116 | ps1='hello'
|
|---|
| 117 | unset ps1[2]
|
|---|
| 118 | unset ${ps1[2]}
|
|---|
| 119 |
|
|---|
| 120 | declare +a ps1
|
|---|
| 121 | declare +a c
|
|---|
| 122 |
|
|---|
| 123 | # the prompt should not print when using a here doc
|
|---|
| 124 | read -p "array test: " -a rv <<!
|
|---|
| 125 | this is a test of read using arrays
|
|---|
| 126 | !
|
|---|
| 127 |
|
|---|
| 128 | echo ${rv[0]} ${rv[4]}
|
|---|
| 129 | echo ${rv[@]}
|
|---|
| 130 |
|
|---|
| 131 | # the variable should be converted to an array when `read -a' is done
|
|---|
| 132 | vv=1
|
|---|
| 133 | read -a vv <<!
|
|---|
| 134 | this is a test of arrays
|
|---|
| 135 | !
|
|---|
| 136 | echo ${vv[0]} ${vv[3]}
|
|---|
| 137 | echo ${vv[@]}
|
|---|
| 138 | unset vv
|
|---|
| 139 |
|
|---|
| 140 | declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
|
|---|
| 141 |
|
|---|
| 142 | export rv
|
|---|
| 143 | #set
|
|---|
| 144 |
|
|---|
| 145 | x[4]=bbb
|
|---|
| 146 | x=abde
|
|---|
| 147 | echo $x
|
|---|
| 148 | echo ${x[0]}
|
|---|
| 149 | echo ${x[4]}
|
|---|
| 150 | echo efgh | ( read x[1] ; echo ${x[1]} )
|
|---|
| 151 | echo wxyz | ( declare -a x ; read x ; echo $x ; echo ${x[0]} )
|
|---|
| 152 |
|
|---|
| 153 | # Make sure that arrays can be used to save the positional paramters verbatim
|
|---|
| 154 | set -- a 'b c' d 'e f g' h
|
|---|
| 155 |
|
|---|
| 156 | ARGV=( [0]=$0 "$@" )
|
|---|
| 157 |
|
|---|
| 158 | for z in "${ARGV[@]}"
|
|---|
| 159 | do
|
|---|
| 160 | echo "$z"
|
|---|
| 161 | done
|
|---|
| 162 |
|
|---|
| 163 | echo "$0"
|
|---|
| 164 | for z in "$@"
|
|---|
| 165 | do
|
|---|
| 166 | echo "$z"
|
|---|
| 167 | done
|
|---|
| 168 |
|
|---|
| 169 | # do various pattern removal and length tests
|
|---|
| 170 | XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
|
|---|
| 171 |
|
|---|
| 172 | xpath=( $( IFS=: ; echo $XPATH ) )
|
|---|
| 173 |
|
|---|
| 174 | echo ${xpath[@]}
|
|---|
| 175 | echo ${xpath[@]##*/}
|
|---|
| 176 | echo ${xpath[0]##*/}
|
|---|
| 177 | echo ${xpath[@]%%[!/]*}
|
|---|
| 178 | echo ${xpath[0]%%[!/]*}
|
|---|
| 179 | recho ${xpath##*/}
|
|---|
| 180 | recho ${xpath%%[!/]*}
|
|---|
| 181 | recho ${xpath[5]##*/}
|
|---|
| 182 | recho ${xpath[5]%%[!/]*}
|
|---|
| 183 |
|
|---|
| 184 | # let's try to make it a DOS-style path
|
|---|
| 185 |
|
|---|
| 186 | zecho "${xpath[@]/\//\\}"
|
|---|
| 187 | zecho "${xpath[@]//\//\\}"
|
|---|
| 188 | zecho "${xpath[@]//[\/]/\\}"
|
|---|
| 189 |
|
|---|
| 190 | # length of the first element of the array, since array without subscript
|
|---|
| 191 | # is equivalent to referencing first element
|
|---|
| 192 | echo ${#xpath} -- ${#xpath[0]}
|
|---|
| 193 |
|
|---|
| 194 | # number of elements in the array
|
|---|
| 195 | nelem=${#xpath[@]}
|
|---|
| 196 | echo ${#xpath[@]} -- $nelem
|
|---|
| 197 |
|
|---|
| 198 | # total length of all elements in the array, including space separators
|
|---|
| 199 | xx="${xpath[*]}"
|
|---|
| 200 | echo ${#xx}
|
|---|
| 201 |
|
|---|
| 202 | # total length of all elements in the array
|
|---|
| 203 | xx=$( IFS='' ; echo "${xpath[*]}" )
|
|---|
| 204 | echo ${#xx}
|
|---|
| 205 |
|
|---|
| 206 | unset xpath[nelem-1]
|
|---|
| 207 |
|
|---|
| 208 | nelem=${#xpath[@]}
|
|---|
| 209 | echo ${#xpath[@]} -- $nelem
|
|---|
| 210 |
|
|---|
| 211 | # arrays and things that look like index assignments
|
|---|
| 212 | array=(42 [1]=14 [2]=44)
|
|---|
| 213 |
|
|---|
| 214 | array2=(grep [ 123 ] \*)
|
|---|
| 215 |
|
|---|
| 216 | echo ${array[@]}
|
|---|
| 217 | echo "${array2[@]}"
|
|---|
| 218 |
|
|---|
| 219 | # arrays and implicit arithmetic evaluation
|
|---|
| 220 | declare -i -a iarray
|
|---|
| 221 |
|
|---|
| 222 | iarray=( 2+4 1+6 7+2 )
|
|---|
| 223 | echo ${iarray[@]}
|
|---|
| 224 |
|
|---|
| 225 | iarray[4]=4+1
|
|---|
| 226 | echo ${iarray[@]}
|
|---|
| 227 |
|
|---|
| 228 | # make sure assignment using the compound assignment syntax removes all
|
|---|
| 229 | # of the old elements from the array value
|
|---|
| 230 | barray=(old1 old2 old3 old4 old5)
|
|---|
| 231 | barray=(new1 new2 new3)
|
|---|
| 232 | echo "length = ${#barray[@]}"
|
|---|
| 233 | echo "value = ${barray[*]}"
|
|---|
| 234 |
|
|---|
| 235 | # make sure the array code behaves correctly with respect to unset variables
|
|---|
| 236 | set -u
|
|---|
| 237 | ( echo ${#narray[4]} )
|
|---|
| 238 |
|
|---|
| 239 | ${THIS_SH} ./array1.sub
|
|---|
| 240 | ${THIS_SH} ./array2.sub
|
|---|
| 241 |
|
|---|
| 242 | # some old bugs and ksh93 compatibility tests
|
|---|
| 243 | ${THIS_SH} ./array3.sub
|
|---|
| 244 |
|
|---|
| 245 | set +u
|
|---|
| 246 | cd /tmp
|
|---|
| 247 |
|
|---|
| 248 | touch 1=bar
|
|---|
| 249 | foo=([10]="bar")
|
|---|
| 250 | echo ${foo[0]}
|
|---|
| 251 | rm 1=bar
|
|---|
| 252 |
|
|---|
| 253 | foo=(a b c d e f g)
|
|---|
| 254 | echo ${foo[@]}
|
|---|
| 255 |
|
|---|
| 256 | # quoted reserved words are ok
|
|---|
| 257 | foo=(\for \case \if \then \else)
|
|---|
| 258 | echo ${foo[@]}
|
|---|
| 259 |
|
|---|
| 260 | # quoted metacharacters are ok
|
|---|
| 261 | foo=( [1]='<>' [2]='<' [3]='>' [4]='!' )
|
|---|
| 262 | echo ${foo[@]}
|
|---|
| 263 |
|
|---|
| 264 | # numbers are just words when not in a redirection context
|
|---|
| 265 | foo=( 12 14 16 18 20 )
|
|---|
| 266 | echo ${foo[@]}
|
|---|
| 267 |
|
|---|
| 268 | foo=( 4414758999202 )
|
|---|
| 269 | echo ${foo[@]}
|
|---|
| 270 |
|
|---|
| 271 | # this was a bug in all versions of bash 2.x up to and including bash-2.04
|
|---|
| 272 | declare -a ddd=(aaa
|
|---|
| 273 | bbb)
|
|---|
| 274 | echo ${ddd[@]}
|
|---|
| 275 |
|
|---|
| 276 | # errors until post-bash-2.05a; now reserved words are OK
|
|---|
| 277 | foo=(a b c for case if then else)
|
|---|
| 278 |
|
|---|
| 279 | foo=(for case if then else)
|
|---|
| 280 |
|
|---|
| 281 | # errors
|
|---|
| 282 | metas=( <> < > ! )
|
|---|
| 283 | metas=( [1]=<> [2]=< [3]=> [4]=! )
|
|---|
| 284 |
|
|---|
| 285 | # various expansions that didn't really work right until post-bash-2.04
|
|---|
| 286 | foo='abc'
|
|---|
| 287 | echo ${foo[0]} ${#foo[0]}
|
|---|
| 288 | echo ${foo[1]} ${#foo[1]}
|
|---|
| 289 | echo ${foo[@]} ${#foo[@]}
|
|---|
| 290 | echo ${foo[*]} ${#foo[*]}
|
|---|
| 291 |
|
|---|
| 292 | foo=''
|
|---|
| 293 | echo ${foo[0]} ${#foo[0]}
|
|---|
| 294 | echo ${foo[1]} ${#foo[1]}
|
|---|
| 295 | echo ${foo[@]} ${#foo[@]}
|
|---|
| 296 | echo ${foo[*]} ${#foo[*]}
|
|---|
| 297 |
|
|---|
| 298 | # new expansions added after bash-2.05b
|
|---|
| 299 | x[0]=zero
|
|---|
| 300 | x[1]=one
|
|---|
| 301 | x[4]=four
|
|---|
| 302 | x[10]=ten
|
|---|
| 303 |
|
|---|
| 304 | recho ${!x[@]}
|
|---|
| 305 | recho "${!x[@]}"
|
|---|
| 306 | recho ${!x[*]}
|
|---|
| 307 | recho "${!x[*]}"
|
|---|
| 308 |
|
|---|
| 309 | # sparse array tests for code fixed in bash-3.0
|
|---|
| 310 | unset av
|
|---|
| 311 | av[1]='one'
|
|---|
| 312 | av[2]=''
|
|---|
| 313 |
|
|---|
| 314 | av[3]=three
|
|---|
| 315 | av[5]=five
|
|---|
| 316 | av[7]=seven
|
|---|
| 317 |
|
|---|
| 318 | echo include null element -- expect one
|
|---|
| 319 | echo ${av[@]:1:2} # what happens when we include a null element?
|
|---|
| 320 | echo include unset element -- expect three five
|
|---|
| 321 | echo ${av[@]:3:2} # what happens when we include an unset element?
|
|---|
| 322 | echo start at unset element -- expect five seven
|
|---|
| 323 | echo ${av[@]:4:2} # what happens when we start at an unset element?
|
|---|
| 324 |
|
|---|
| 325 | echo too many elements -- expect three five seven
|
|---|
| 326 | echo ${av[@]:3:5} # how about too many elements?
|
|---|
| 327 |
|
|---|
| 328 | echo positive offset - expect five seven
|
|---|
| 329 | echo ${av[@]:5:2}
|
|---|
| 330 | echo negative offset to unset element - expect seven
|
|---|
| 331 | echo ${av[@]: -2:2}
|
|---|
| 332 |
|
|---|
| 333 | echo positive offset 2 - expect seven
|
|---|
| 334 | echo ${av[@]: 6:2}
|
|---|
| 335 | echo negative offset 2 - expect seven
|
|---|
| 336 | echo ${av[@]: -1:2}
|
|---|
| 337 |
|
|---|
| 338 | echo out-of-range offset
|
|---|
| 339 | echo ${av[@]:12}
|
|---|
| 340 |
|
|---|
| 341 | # parsing problems and other inconsistencies not fixed until post bash-3.0
|
|---|
| 342 | unset x
|
|---|
| 343 | declare -a x=(')' $$)
|
|---|
| 344 | [ ${x[1]} -eq $$ ] || echo bad
|
|---|
| 345 |
|
|---|
| 346 | unset x
|
|---|
| 347 | declare -a x=(a b c d e)
|
|---|
| 348 | echo ${x[4]}
|
|---|
| 349 |
|
|---|
| 350 | z=([1]=one [4]=four [7]=seven [10]=ten)
|
|---|
| 351 |
|
|---|
| 352 | echo ${#z[@]}
|
|---|
| 353 |
|
|---|
| 354 | echo ${!z[@]}
|
|---|
| 355 |
|
|---|
| 356 | unset x
|
|---|
| 357 | declare -a x=(a \'b c\')
|
|---|
| 358 |
|
|---|
| 359 | echo "${x[1]}"
|
|---|
| 360 |
|
|---|
| 361 | unset x
|
|---|
| 362 | declare -a x=(a 'b c')
|
|---|
| 363 |
|
|---|
| 364 | echo "${x[1]}"
|
|---|
| 365 |
|
|---|
| 366 | unset x
|
|---|
| 367 | declare -a x=($0)
|
|---|
| 368 | [ "${x[@]}" = $0 ] || echo double expansion of \$0
|
|---|
| 369 | declare -a x=(\$0)
|
|---|
| 370 | echo "${x[@]}"
|
|---|
| 371 |
|
|---|
| 372 | : ${TMPDIR:=/tmp}
|
|---|
| 373 |
|
|---|
| 374 | mkdir $TMPDIR/bash-test-$$
|
|---|
| 375 | cd $TMPDIR/bash-test-$$
|
|---|
| 376 |
|
|---|
| 377 | trap "cd / ; rm -rf $TMPDIR/bash-test-$$" 0 1 2 3 6 15
|
|---|
| 378 |
|
|---|
| 379 | touch '[3]=abcde'
|
|---|
| 380 |
|
|---|
| 381 | touch r s t u v
|
|---|
| 382 |
|
|---|
| 383 | declare -a x=(*)
|
|---|
| 384 |
|
|---|
| 385 | echo ${x[3]}
|
|---|
| 386 | echo ${x[@]}
|
|---|
| 387 |
|
|---|
| 388 | unset x
|
|---|
| 389 | x=(a b c d e)
|
|---|
| 390 |
|
|---|
| 391 | echo ${x[*]: -1}
|
|---|
| 392 |
|
|---|
| 393 | unset x[4]
|
|---|
| 394 | unset x[2]
|
|---|
| 395 |
|
|---|
| 396 | x[9]='9'
|
|---|
| 397 |
|
|---|
| 398 | echo ${x[*]: -1}
|
|---|