| 1 | ## compare_shells: bash-4.4
 | 
| 2 | ## oils_failures_allowed: 3
 | 
| 3 | 
 | 
| 4 | 
 | 
| 5 | # NOTE:
 | 
| 6 | # -declare -A is required.
 | 
| 7 | #
 | 
| 8 | # Simply doing:
 | 
| 9 | # a=([aa]=b [foo]=bar ['a+1']=c)
 | 
| 10 | # gets utterly bizarre behavior.
 | 
| 11 | #
 | 
| 12 | # Associtative Arrays are COMPLETELY bash-specific.  mksh doesn't even come
 | 
| 13 | # close.  So I will probably not implement them, or implement something
 | 
| 14 | # slightly different, because the semantics are just weird.
 | 
| 15 | 
 | 
| 16 | # http://www.gnu.org/software/bash/manual/html_node/Arrays.html
 | 
| 17 | # TODO: Need a SETUP section.
 | 
| 18 | 
 | 
| 19 | #### Literal syntax ([x]=y)
 | 
| 20 | declare -A a
 | 
| 21 | a=([aa]=b [foo]=bar ['a+1']=c)
 | 
| 22 | echo ${a["aa"]}
 | 
| 23 | echo ${a["foo"]}
 | 
| 24 | echo ${a["a+1"]}
 | 
| 25 | ## STDOUT:
 | 
| 26 | b
 | 
| 27 | bar
 | 
| 28 | c
 | 
| 29 | ## END
 | 
| 30 | 
 | 
| 31 | #### set associative array to indexed array literal (very surprising bash behavior)
 | 
| 32 | declare -A assoc=([k1]=foo [k2]='spam eggs')
 | 
| 33 | for v in "${assoc[@]}"; do echo $v; done | sort
 | 
| 34 | for v in "${!assoc[@]}"; do echo $v; done | sort
 | 
| 35 | 
 | 
| 36 | # disallow this in OSH?  Changing type?
 | 
| 37 | 
 | 
| 38 | assoc=(foo 'spam eggs')
 | 
| 39 | argv.py "${assoc[@]}"
 | 
| 40 | argv.py "${!assoc[@]}"
 | 
| 41 | 
 | 
| 42 | ## STDOUT:
 | 
| 43 | foo
 | 
| 44 | spam eggs
 | 
| 45 | k1
 | 
| 46 | k2
 | 
| 47 | ['foo', 'spam eggs']
 | 
| 48 | ['0', '1']
 | 
| 49 | ## END
 | 
| 50 | ## BUG bash STDOUT:
 | 
| 51 | foo
 | 
| 52 | spam eggs
 | 
| 53 | k1
 | 
| 54 | k2
 | 
| 55 | []
 | 
| 56 | []
 | 
| 57 | ## END
 | 
| 58 | 
 | 
| 59 | #### Can't initialize assoc array with indexed array
 | 
| 60 | declare -A A=(1 2 3)
 | 
| 61 | echo status=$?
 | 
| 62 | ## STDOUT:
 | 
| 63 | status=2
 | 
| 64 | ## END
 | 
| 65 | 
 | 
| 66 | # bash prints warnings to stderr but gives no indication of the problem
 | 
| 67 | ## BUG bash STDOUT:
 | 
| 68 | status=0
 | 
| 69 | ## END
 | 
| 70 | 
 | 
| 71 | 
 | 
| 72 | #### Initializing indexed array with assoc array
 | 
| 73 | declare -a a=([xx]=1 [yy]=2 [zz]=3)
 | 
| 74 | echo status=$?
 | 
| 75 | argv.py "${a[@]}"
 | 
| 76 | ## STDOUT:
 | 
| 77 | status=2
 | 
| 78 | []
 | 
| 79 | ## END
 | 
| 80 | ## BUG bash STDOUT:
 | 
| 81 | status=0
 | 
| 82 | ['3']
 | 
| 83 | ## END
 | 
| 84 | 
 | 
| 85 | #### create empty assoc array, put, then get
 | 
| 86 | declare -A A  # still undefined
 | 
| 87 | argv.py "${A[@]}"
 | 
| 88 | argv.py "${!A[@]}"
 | 
| 89 | A['foo']=bar
 | 
| 90 | echo ${A['foo']}
 | 
| 91 | ## STDOUT:
 | 
| 92 | []
 | 
| 93 | []
 | 
| 94 | bar
 | 
| 95 | ## END
 | 
| 96 | 
 | 
| 97 | #### Empty value (doesn't use EmptyWord?)
 | 
| 98 | declare -A A=(["k"]= )
 | 
| 99 | argv.py "${A["k"]}"
 | 
| 100 | ## STDOUT:
 | 
| 101 | ['']
 | 
| 102 | ## END
 | 
| 103 | 
 | 
| 104 | #### retrieve keys with !
 | 
| 105 | declare -A a
 | 
| 106 | var='x'
 | 
| 107 | a["$var"]=b
 | 
| 108 | a['foo']=bar
 | 
| 109 | a['a+1']=c
 | 
| 110 | for key in "${!a[@]}"; do
 | 
| 111 |   echo $key
 | 
| 112 | done | sort
 | 
| 113 | ## STDOUT:
 | 
| 114 | a+1
 | 
| 115 | foo
 | 
| 116 | x
 | 
| 117 | ## END
 | 
| 118 | 
 | 
| 119 | #### retrieve values with ${A[@]}
 | 
| 120 | declare -A A
 | 
| 121 | var='x'
 | 
| 122 | A["$var"]=b
 | 
| 123 | A['foo']=bar
 | 
| 124 | A['a+1']=c
 | 
| 125 | for val in "${A[@]}"; do
 | 
| 126 |   echo $val
 | 
| 127 | done | sort
 | 
| 128 | ## STDOUT:
 | 
| 129 | b
 | 
| 130 | bar
 | 
| 131 | c
 | 
| 132 | ## END
 | 
| 133 | 
 | 
| 134 | #### coerce to string with ${A[*]}, etc.
 | 
| 135 | declare -A A
 | 
| 136 | A['X X']=xx
 | 
| 137 | A['Y Y']=yy
 | 
| 138 | argv.py "${A[*]}"
 | 
| 139 | argv.py "${!A[*]}"
 | 
| 140 | 
 | 
| 141 | argv.py ${A[@]}
 | 
| 142 | argv.py ${!A[@]}
 | 
| 143 | ## STDOUT:
 | 
| 144 | ['xx yy']
 | 
| 145 | ['X X Y Y']
 | 
| 146 | ['xx', 'yy']
 | 
| 147 | ['X', 'X', 'Y', 'Y']
 | 
| 148 | ## END
 | 
| 149 | 
 | 
| 150 | #### ${A[@]/b/B} 
 | 
| 151 | # but ${!A[@]/b/B} doesn't work
 | 
| 152 | declare -A A
 | 
| 153 | A['aa']=bbb
 | 
| 154 | A['bb']=ccc
 | 
| 155 | A['cc']=ddd
 | 
| 156 | for val in "${A[@]//b/B}"; do
 | 
| 157 |   echo $val
 | 
| 158 | done | sort
 | 
| 159 | ## STDOUT:
 | 
| 160 | BBB
 | 
| 161 | ccc
 | 
| 162 | ddd
 | 
| 163 | ## END
 | 
| 164 | 
 | 
| 165 | #### ${A[@]#prefix}
 | 
| 166 | declare -A A
 | 
| 167 | A['aa']=one
 | 
| 168 | A['bb']=two
 | 
| 169 | A['cc']=three
 | 
| 170 | for val in "${A[@]#t}"; do
 | 
| 171 |   echo $val
 | 
| 172 | done | sort
 | 
| 173 | ## STDOUT:
 | 
| 174 | hree
 | 
| 175 | one
 | 
| 176 | wo
 | 
| 177 | ## END
 | 
| 178 | 
 | 
| 179 | #### ${assoc} is like ${assoc[0]}
 | 
| 180 | declare -A a
 | 
| 181 | 
 | 
| 182 | a=([aa]=b [foo]=bar ['a+1']=c)
 | 
| 183 | echo a="${a}"
 | 
| 184 | 
 | 
| 185 | a=([0]=zzz)
 | 
| 186 | echo a="${a}"
 | 
| 187 | 
 | 
| 188 | a=(['0']=yyy)
 | 
| 189 | echo a="${a}"
 | 
| 190 | 
 | 
| 191 | ## STDOUT:
 | 
| 192 | a=
 | 
| 193 | a=zzz
 | 
| 194 | a=yyy
 | 
| 195 | ## END
 | 
| 196 | 
 | 
| 197 | #### length ${#a[@]}
 | 
| 198 | declare -A a
 | 
| 199 | a["x"]=1
 | 
| 200 | a["y"]=2
 | 
| 201 | a["z"]=3
 | 
| 202 | echo "${#a[@]}"
 | 
| 203 | ## stdout: 3
 | 
| 204 | 
 | 
| 205 | #### lookup with ${a[0]} -- "0" is a string
 | 
| 206 | declare -A a
 | 
| 207 | a["0"]=a
 | 
| 208 | a["1"]=b
 | 
| 209 | a["2"]=c
 | 
| 210 | echo 0 "${a[0]}" 1 "${a[1]}" 2 "${a[2]}"
 | 
| 211 | ## STDOUT:
 | 
| 212 | 0 a 1 b 2 c
 | 
| 213 | ## END
 | 
| 214 | 
 | 
| 215 | #### lookup with double quoted strings "mykey"
 | 
| 216 | declare -A a
 | 
| 217 | a["aa"]=b
 | 
| 218 | a["foo"]=bar
 | 
| 219 | a['a+1']=c
 | 
| 220 | echo "${a["aa"]}" "${a["foo"]}" "${a["a+1"]}"
 | 
| 221 | ## STDOUT:
 | 
| 222 | b bar c
 | 
| 223 | ## END
 | 
| 224 | 
 | 
| 225 | #### lookup with single quoted string
 | 
| 226 | declare -A a
 | 
| 227 | a["aa"]=b
 | 
| 228 | a["foo"]=bar
 | 
| 229 | a['a+1']=c
 | 
| 230 | echo "${a['a+1']}"
 | 
| 231 | ## stdout: c
 | 
| 232 | 
 | 
| 233 | #### lookup with unquoted $key and quoted "$i$i"
 | 
| 234 | declare -A A
 | 
| 235 | A["aa"]=b
 | 
| 236 | A["foo"]=bar
 | 
| 237 | 
 | 
| 238 | key=foo
 | 
| 239 | echo ${A[$key]}
 | 
| 240 | i=a
 | 
| 241 | echo ${A["$i$i"]}   # note: ${A[$i$i]} doesn't work in OSH
 | 
| 242 | ## STDOUT:
 | 
| 243 | bar
 | 
| 244 | b
 | 
| 245 | ## END
 | 
| 246 | 
 | 
| 247 | #### lookup by unquoted string doesn't work in OSH because it's a variable
 | 
| 248 | declare -A a
 | 
| 249 | a["aa"]=b
 | 
| 250 | a["foo"]=bar
 | 
| 251 | a['a+1']=c
 | 
| 252 | echo "${a[a+1]}"
 | 
| 253 | ## stdout-json: ""
 | 
| 254 | ## status: 1
 | 
| 255 | ## BUG bash stdout: c
 | 
| 256 | ## BUG bash status: 0
 | 
| 257 | 
 | 
| 258 | #### bash bug: "i+1" and i+1 are the same key
 | 
| 259 | 
 | 
| 260 | i=1
 | 
| 261 | array=(5 6 7)
 | 
| 262 | echo array[i]="${array[i]}"
 | 
| 263 | echo array[i+1]="${array[i+1]}"
 | 
| 264 | 
 | 
| 265 | # arithmetic does NOT work here in bash.  These are unquoted strings!
 | 
| 266 | declare -A assoc
 | 
| 267 | assoc[i]=$i
 | 
| 268 | assoc[i+1]=$i+1
 | 
| 269 | 
 | 
| 270 | assoc["i"]=string
 | 
| 271 | assoc["i+1"]=string+1
 | 
| 272 | 
 | 
| 273 | echo assoc[i]="${assoc[i]}" 
 | 
| 274 | echo assoc[i+1]="${assoc[i+1]}"
 | 
| 275 | 
 | 
| 276 | echo assoc[i]="${assoc["i"]}" 
 | 
| 277 | echo assoc[i+1]="${assoc["i+1"]}"
 | 
| 278 | 
 | 
| 279 | ## status: 1
 | 
| 280 | ## STDOUT:
 | 
| 281 | array[i]=6
 | 
| 282 | array[i+1]=7
 | 
| 283 | ## END
 | 
| 284 | ## BUG bash status: 0
 | 
| 285 | ## BUG bash STDOUT:
 | 
| 286 | array[i]=6
 | 
| 287 | array[i+1]=7
 | 
| 288 | assoc[i]=string
 | 
| 289 | assoc[i+1]=string+1
 | 
| 290 | assoc[i]=string
 | 
| 291 | assoc[i+1]=string+1
 | 
| 292 | ## END
 | 
| 293 | 
 | 
| 294 | #### Array stored in associative array gets converted to string (without strict_array)
 | 
| 295 | 
 | 
| 296 | array=('1 2' 3)
 | 
| 297 | declare -A d
 | 
| 298 | d['key']="${array[@]}"
 | 
| 299 | argv.py "${d['key']}"
 | 
| 300 | ## stdout: ['1 2 3']
 | 
| 301 | 
 | 
| 302 | #### Indexed array as key of associative array coerces to string (without shopt -s strict_array)
 | 
| 303 | 
 | 
| 304 | declare -a array=(1 2 3)
 | 
| 305 | declare -A assoc
 | 
| 306 | assoc[42]=43
 | 
| 307 | assoc["${array[@]}"]=foo
 | 
| 308 | 
 | 
| 309 | echo "${assoc["${array[@]}"]}"
 | 
| 310 | for entry in "${!assoc[@]}"; do
 | 
| 311 |   echo $entry
 | 
| 312 | done | sort
 | 
| 313 | 
 | 
| 314 | ## STDOUT:
 | 
| 315 | foo
 | 
| 316 | 1 2 3
 | 
| 317 | 42
 | 
| 318 | ## END
 | 
| 319 | 
 | 
| 320 | #### Append to associative array value A['x']+='suffix'
 | 
| 321 | declare -A A
 | 
| 322 | A['x']='foo'
 | 
| 323 | A['x']+='bar'
 | 
| 324 | A['x']+='bar'
 | 
| 325 | argv.py "${A["x"]}"
 | 
| 326 | ## STDOUT:
 | 
| 327 | ['foobarbar']
 | 
| 328 | ## END
 | 
| 329 | 
 | 
| 330 | #### Slice of associative array doesn't make sense in bash
 | 
| 331 | declare -A a
 | 
| 332 | a[xx]=1
 | 
| 333 | a[yy]=2
 | 
| 334 | a[zz]=3
 | 
| 335 | a[aa]=4
 | 
| 336 | a[bb]=5
 | 
| 337 | #argv.py ${a["xx"]}
 | 
| 338 | argv.py ${a[@]: 0: 3}
 | 
| 339 | argv.py ${a[@]: 1: 3}
 | 
| 340 | argv.py ${a[@]: 2: 3}
 | 
| 341 | argv.py ${a[@]: 3: 3}
 | 
| 342 | argv.py ${a[@]: 4: 3}
 | 
| 343 | argv.py ${a[@]: 5: 3}
 | 
| 344 | ## stdout-json: ""
 | 
| 345 | ## status: 1
 | 
| 346 | ## BUG bash STDOUT:
 | 
| 347 | ['2', '1', '5']
 | 
| 348 | ['2', '1', '5']
 | 
| 349 | ['1', '5', '4']
 | 
| 350 | ['5', '4', '3']
 | 
| 351 | ['4', '3']
 | 
| 352 | ['3']
 | 
| 353 | ## END
 | 
| 354 | ## BUG bash status: 0
 | 
| 355 | 
 | 
| 356 | #### bash variable can have an associative array part and a string part
 | 
| 357 | 
 | 
| 358 | # and $assoc is equivalent to ${assoc[0]}, just like regular arrays
 | 
| 359 | declare -A assoc
 | 
| 360 | assoc[1]=1
 | 
| 361 | assoc[2]=2
 | 
| 362 | echo ${assoc[1]} ${assoc[2]} ${assoc}
 | 
| 363 | assoc[0]=zero
 | 
| 364 | echo ${assoc[1]} ${assoc[2]} ${assoc}
 | 
| 365 | assoc=string
 | 
| 366 | echo ${assoc[1]} ${assoc[2]} ${assoc}
 | 
| 367 | ## STDOUT:
 | 
| 368 | 1 2
 | 
| 369 | 1 2 zero
 | 
| 370 | 1 2 string
 | 
| 371 | ## END
 | 
| 372 | ## N-I osh status: 1
 | 
| 373 | ## N-I osh STDOUT:
 | 
| 374 | 1 2
 | 
| 375 | 1 2 zero
 | 
| 376 | ## END
 | 
| 377 | 
 | 
| 378 | #### Associative array expressions inside (( )) with keys that look like numbers
 | 
| 379 | declare -A assoc
 | 
| 380 | assoc[0]=42
 | 
| 381 | (( var = ${assoc[0]} ))
 | 
| 382 | echo $var
 | 
| 383 | (( var = assoc[0] ))
 | 
| 384 | echo $var
 | 
| 385 | ## STDOUT:
 | 
| 386 | 42
 | 
| 387 | 42
 | 
| 388 | ## END
 | 
| 389 | 
 | 
| 390 | #### (( A[5] += 42 ))
 | 
| 391 | declare -A A
 | 
| 392 | (( A[5] = 10 ))
 | 
| 393 | (( A[5] += 6 ))
 | 
| 394 | echo ${A[5]}
 | 
| 395 | ## STDOUT:
 | 
| 396 | 16
 | 
| 397 | ## END
 | 
| 398 | 
 | 
| 399 | #### (( A[5] += 42 )) with empty cell
 | 
| 400 | shopt -u strict_arith  # default zero cell
 | 
| 401 | declare -A A
 | 
| 402 | (( A[5] += 6 ))
 | 
| 403 | echo ${A[5]}
 | 
| 404 | ## STDOUT:
 | 
| 405 | 6
 | 
| 406 | ## END
 | 
| 407 | 
 | 
| 408 | #### setting key to itself (from bash-bug mailing list)
 | 
| 409 | declare -A foo
 | 
| 410 | foo=(["key"]="value1")
 | 
| 411 | echo ${foo["key"]}
 | 
| 412 | foo=(["key"]="${foo["key"]} value2")
 | 
| 413 | echo ${foo["key"]}
 | 
| 414 | ## STDOUT:
 | 
| 415 | value1
 | 
| 416 | value1 value2
 | 
| 417 | ## END
 | 
| 418 | ## BUG bash STDOUT:
 | 
| 419 | value1
 | 
| 420 | value2
 | 
| 421 | ## END
 | 
| 422 | 
 | 
| 423 | #### readonly associative array can't be modified
 | 
| 424 | declare -Ar A
 | 
| 425 | A['x']=1
 | 
| 426 | echo status=$?
 | 
| 427 | ## OK osh status: 1
 | 
| 428 | ## OK osh stdout-json: ""
 | 
| 429 | ## STDOUT:
 | 
| 430 | status=1
 | 
| 431 | ## END
 | 
| 432 | 
 | 
| 433 | #### associative array and brace expansion
 | 
| 434 | declare -A A=([k1]=v [k2]=-{a,b}-)
 | 
| 435 | echo ${A["k1"]}
 | 
| 436 | echo ${A["k2"]}
 | 
| 437 | ## STDOUT:
 | 
| 438 | v
 | 
| 439 | -{a,b}-
 | 
| 440 | ## END
 | 
| 441 | 
 | 
| 442 | #### bash mangles array #1
 | 
| 443 | a=([k1]=v1 [k2]=v2)
 | 
| 444 | echo ${a["k1"]}
 | 
| 445 | echo ${a["k2"]}
 | 
| 446 | ## STDOUT:
 | 
| 447 | v1
 | 
| 448 | v2
 | 
| 449 | ## END
 | 
| 450 | ## BUG bash STDOUT:
 | 
| 451 | v2
 | 
| 452 | v2
 | 
| 453 | ## END
 | 
| 454 | 
 | 
| 455 | #### bash mangles array and brace #2
 | 
| 456 | a=([k2]=-{a,b}-)
 | 
| 457 | echo ${a["k2"]}
 | 
| 458 | ## STDOUT:
 | 
| 459 | -{a,b}-
 | 
| 460 | ## END
 | 
| 461 | ## BUG bash STDOUT:
 | 
| 462 | [k2]=-a-
 | 
| 463 | ## END
 | 
| 464 | 
 | 
| 465 | #### declare -A A=() allowed
 | 
| 466 | set -o nounset
 | 
| 467 | shopt -s strict_arith || true
 | 
| 468 | 
 | 
| 469 | declare -A ASSOC=()
 | 
| 470 | echo len=${#ASSOC[@]}
 | 
| 471 | 
 | 
| 472 | # Check that it really can be used like an associative array
 | 
| 473 | ASSOC['k']='32'
 | 
| 474 | echo len=${#ASSOC[@]}
 | 
| 475 | 
 | 
| 476 | # bash allows a variable to be an associative array AND unset, while OSH
 | 
| 477 | # doesn't
 | 
| 478 | set +o nounset
 | 
| 479 | declare -A u
 | 
| 480 | echo unset len=${#u[@]}
 | 
| 481 | ## STDOUT:
 | 
| 482 | len=0
 | 
| 483 | len=1
 | 
| 484 | unset len=0
 | 
| 485 | ## END
 | 
| 486 | 
 | 
| 487 | #### unset -v and assoc array
 | 
| 488 | shopt -s eval_unsafe_arith || true
 | 
| 489 | 
 | 
| 490 | show-len() {
 | 
| 491 |   echo len=${#assoc[@]}
 | 
| 492 | }
 | 
| 493 | 
 | 
| 494 | declare -A assoc=(['K']=val)
 | 
| 495 | show-len
 | 
| 496 | 
 | 
| 497 | unset -v 'assoc["K"]'
 | 
| 498 | show-len
 | 
| 499 | 
 | 
| 500 | declare -A assoc=(['K']=val)
 | 
| 501 | show-len
 | 
| 502 | key=K
 | 
| 503 | unset -v 'assoc[$key]'
 | 
| 504 | show-len
 | 
| 505 | 
 | 
| 506 | declare -A assoc=(['K']=val)
 | 
| 507 | show-len
 | 
| 508 | unset -v 'assoc[$(echo K)]'
 | 
| 509 | show-len
 | 
| 510 | 
 | 
| 511 | # ${prefix} doesn't work here, even though it does in arithmetic
 | 
| 512 | #declare -A assoc=(['K']=val)
 | 
| 513 | #show-len
 | 
| 514 | #prefix=as
 | 
| 515 | #unset -v '${prefix}soc[$key]'
 | 
| 516 | #show-len
 | 
| 517 | 
 | 
| 518 | ## STDOUT:
 | 
| 519 | len=1
 | 
| 520 | len=0
 | 
| 521 | len=1
 | 
| 522 | len=0
 | 
| 523 | len=1
 | 
| 524 | len=0
 | 
| 525 | ## END
 | 
| 526 | 
 | 
| 527 | #### nameref and assoc array
 | 
| 528 | show-values() {
 | 
| 529 |   echo values: ${A[@]}
 | 
| 530 | }
 | 
| 531 | 
 | 
| 532 | declare -A A=(['K']=val)
 | 
| 533 | show-values
 | 
| 534 | 
 | 
| 535 | declare -n ref='A["K"]'
 | 
| 536 | echo before $ref
 | 
| 537 | ref='val2'
 | 
| 538 | echo after $ref
 | 
| 539 | show-values
 | 
| 540 | 
 | 
| 541 | echo ---
 | 
| 542 | 
 | 
| 543 | key=K
 | 
| 544 | declare -n ref='A[$key]'
 | 
| 545 | echo before $ref
 | 
| 546 | ref='val3'
 | 
| 547 | echo after $ref
 | 
| 548 | show-values
 | 
| 549 | 
 | 
| 550 | ## STDOUT:
 | 
| 551 | values: val
 | 
| 552 | before val
 | 
| 553 | after val2
 | 
| 554 | values: val2
 | 
| 555 | ---
 | 
| 556 | before val2
 | 
| 557 | after val3
 | 
| 558 | values: val3
 | 
| 559 | ## END
 | 
| 560 | 
 | 
| 561 | #### ${!ref} and assoc array
 | 
| 562 | 
 | 
| 563 | show-values() {
 | 
| 564 |   echo values: ${A[@]}
 | 
| 565 | }
 | 
| 566 | 
 | 
| 567 | declare -A A=(['K']=val)
 | 
| 568 | show-values
 | 
| 569 | 
 | 
| 570 | declare ref='A["K"]'
 | 
| 571 | echo ref ${!ref}
 | 
| 572 | 
 | 
| 573 | key=K
 | 
| 574 | declare ref='A[$key]'
 | 
| 575 | echo ref ${!ref}
 | 
| 576 | 
 | 
| 577 | ## STDOUT:
 | 
| 578 | values: val
 | 
| 579 | ref val
 | 
| 580 | ref val
 | 
| 581 | ## END
 | 
| 582 | 
 | 
| 583 | #### printf -v and assoc array
 | 
| 584 | 
 | 
| 585 | show-values() {
 | 
| 586 |   echo values: ${assoc[@]}
 | 
| 587 | }
 | 
| 588 | 
 | 
| 589 | declare -A assoc=(['K']=val)
 | 
| 590 | show-values
 | 
| 591 | 
 | 
| 592 | printf -v 'assoc["K"]' '/%s/' val2
 | 
| 593 | show-values
 | 
| 594 | 
 | 
| 595 | key=K
 | 
| 596 | printf -v 'assoc[$key]' '/%s/' val3
 | 
| 597 | show-values
 | 
| 598 | 
 | 
| 599 | # Somehow bash doesn't allow this
 | 
| 600 | #prefix=as
 | 
| 601 | #printf -v '${prefix}soc[$key]' '/%s/' val4
 | 
| 602 | #show-values
 | 
| 603 | 
 | 
| 604 | ## STDOUT:
 | 
| 605 | values: val
 | 
| 606 | values: /val2/
 | 
| 607 | values: /val3/
 | 
| 608 | ## END
 | 
| 609 | 
 | 
| 610 | #### bash bug: (( A["$key"] = 1 )) doesn't work
 | 
| 611 | key='\'
 | 
| 612 | declare -A A
 | 
| 613 | #A["$key"]=1
 | 
| 614 | 
 | 
| 615 | # Works in both
 | 
| 616 | #A["$key"]=42
 | 
| 617 | 
 | 
| 618 | # Works in bash only
 | 
| 619 | #(( A[\$key] = 42 ))
 | 
| 620 | 
 | 
| 621 | (( A["$key"] = 42 ))
 | 
| 622 | 
 | 
| 623 | argv.py "${!A[@]}"
 | 
| 624 | argv.py "${A[@]}"
 | 
| 625 | ## STDOUT:
 | 
| 626 | ['\\']
 | 
| 627 | ['42']
 | 
| 628 | ## END
 | 
| 629 | ## BUG bash STDOUT:
 | 
| 630 | []
 | 
| 631 | []
 | 
| 632 | ## END
 | 
| 633 | 
 | 
| 634 | 
 | 
| 635 | #### Implicit increment of keys
 | 
| 636 | declare -a arr=( [30]=a b [40]=x y)
 | 
| 637 | argv.py "${!arr[@]}"
 | 
| 638 | argv.py "${arr[@]}"
 | 
| 639 | 
 | 
| 640 | # osh says "expected associative array pair"
 | 
| 641 | 
 | 
| 642 | ## STDOUT:
 | 
| 643 | ['30', '31', '40', '41']
 | 
| 644 | ['a', 'b', 'x', 'y']
 | 
| 645 | ## END
 |