| 1 | #!/usr/bin/env bash
|
| 2 | #
|
| 3 | # Demo of variable scope.
|
| 4 |
|
| 5 | #set -o nounset
|
| 6 | set -o pipefail
|
| 7 | set -o errexit
|
| 8 |
|
| 9 | printenv() {
|
| 10 | spec/bin/printenv.py "$@"
|
| 11 | }
|
| 12 |
|
| 13 | my_global=G1
|
| 14 |
|
| 15 | myfunc() {
|
| 16 | # This makes a NEW local variable my_global.
|
| 17 | # Yeah I think this is amenable to static analysis.
|
| 18 | local loc1=L1 my_global loc2=L2
|
| 19 |
|
| 20 | my_global=LL
|
| 21 | echo "my_global in function: $my_global"
|
| 22 |
|
| 23 | loc1=L3
|
| 24 | echo "loc1: $loc1 loc2: $loc2"
|
| 25 |
|
| 26 | # TODO: Add declare
|
| 27 | }
|
| 28 |
|
| 29 | func2() {
|
| 30 | my_global=G2
|
| 31 | func2_global=G3
|
| 32 |
|
| 33 | local func2_local=A
|
| 34 |
|
| 35 | inner_func() {
|
| 36 | echo "called inner_func"
|
| 37 | #set -o nounset
|
| 38 | # Not defined anymore
|
| 39 | echo "func2_local: $func2_local"
|
| 40 | }
|
| 41 | }
|
| 42 |
|
| 43 | # Doesn't work until func2 is run
|
| 44 | inner_func || echo "inner_func not defined yet"
|
| 45 |
|
| 46 | myfunc
|
| 47 | echo "my_global: $my_global"
|
| 48 |
|
| 49 | func2
|
| 50 |
|
| 51 | # This is defined outside
|
| 52 | inner_func
|
| 53 |
|
| 54 | echo "AFTER mutation my_global: $my_global"
|
| 55 | echo "func2_global $func2_global"
|
| 56 |
|
| 57 | # These don't leak
|
| 58 | echo "loc1: $loc1 loc2: $loc2"
|
| 59 |
|
| 60 | # Nothing can be combined. Only one keyword. Use declare flags to combine.
|
| 61 | combined() {
|
| 62 | local __LOCAL=1
|
| 63 | export __ONE=one
|
| 64 | export local __TWO=two
|
| 65 | export readonly __THREE=three
|
| 66 |
|
| 67 | # does not work!
|
| 68 | local export __FOUR=four
|
| 69 | # does not work!
|
| 70 | readonly export __FIVE=five
|
| 71 |
|
| 72 | readonly local __SIX=six
|
| 73 | echo $SIX
|
| 74 |
|
| 75 | local readonly __SEVEN=seven
|
| 76 | echo $SEVEN
|
| 77 | #echo "readonly: [$readonly]"
|
| 78 |
|
| 79 | # This doesn't work!
|
| 80 | export readonly local __EIGHT=eight
|
| 81 |
|
| 82 | printenv __ONE __TWO __THREE __FOUR __FIVE __SIX __SEVEN __EIGHT
|
| 83 | # export can come first, but local can't come first
|
| 84 |
|
| 85 | # These are both -a
|
| 86 | local __array=(1 2 3)
|
| 87 | local __array2=([a]=1 [b]=2 [c]=3)
|
| 88 |
|
| 89 | # This gets -A
|
| 90 | local -A __array3=([a]=1 [b]=2 [c]=3)
|
| 91 |
|
| 92 | # Doesn't get any flags. global/local is NOT a flag! It's about the
|
| 93 | # position in the symbol tables I guess.
|
| 94 | declare -g __global=g
|
| 95 |
|
| 96 | declare -p | grep __
|
| 97 | }
|
| 98 |
|
| 99 | __GLOBAL=foo
|
| 100 |
|
| 101 | combined
|
| 102 | echo GLOBAL
|
| 103 | declare -p | grep __
|
| 104 |
|
| 105 | conditional-local() {
|
| 106 | if test $# -eq 0; then
|
| 107 | echo DEFINING LOCAL
|
| 108 | local x=1
|
| 109 | echo $x
|
| 110 | else
|
| 111 | echo DEFINING GLOBAL
|
| 112 | x=2
|
| 113 | echo $x
|
| 114 | fi
|
| 115 |
|
| 116 | x=3
|
| 117 | echo $x
|
| 118 | }
|
| 119 |
|
| 120 | conditional-local
|
| 121 | echo $x # x is not defined
|
| 122 |
|
| 123 | conditional-local foo
|
| 124 | echo $x # x is not defined
|
| 125 |
|
| 126 |
|