scoping.sh 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #! /bin/bash
  2. # explore/demonstrate scoping in bash
  3. unset FOO
  4. #
  5. # Testing scoping of variables to/from functions
  6. #
  7. # Q: Do functions inherit variables from outer scope?
  8. #
  9. FOO=FOO-outside
  10. function baz { echo FOO is $FOO; }
  11. baz
  12. # output is "FOO-outside".
  13. #
  14. # A: yes. $FOO comes from outer scope
  15. # Q: when does variable expansion happen
  16. #
  17. FOO=FOO-outside2
  18. baz
  19. # output is "FOO-outside2"
  20. #
  21. # A: expansion of $FOO hapens at baz runtime, not when defined.
  22. # Q: are variables global?
  23. #
  24. function blort { FOO=foo-inside; echo FOO inside is $FOO; }
  25. echo $FOO
  26. # FOO is "inside before calling the function"
  27. blort
  28. # ouput is "FOO inside is foo-inside"
  29. echo $FOO
  30. # output is "foo-inside"
  31. #
  32. # A: scope of of variableis global
  33. #
  34. # Exporting variables to subshells
  35. #
  36. $ export -p | grep FOO
  37. $ # FOO is not exported
  38. $ FOO=bar
  39. $ export -p | grep FOO
  40. $ # FOO is still not exported
  41. $ export FOO=baz
  42. $ export -p | grep FOO
  43. declare -x FOO="baz"
  44. # Q: but as we see below, non-exported variables are
  45. # inherited by subproceses (probably as a conseuqence
  46. # of fork(2). When are exports neeed?
  47. #
  48. # Testing scoping of varibles in subshells
  49. #
  50. # Q: are variable in a sub-shell local to that shell?
  51. unset FOO
  52. FOO=bar
  53. function blort {
  54. (
  55. echo FOO inside blort is $FOO;
  56. FOO=foo-inside;
  57. echo FOO inside blort is $FOO after setting
  58. )
  59. }
  60. blort
  61. echo FOO outside blort after call to baz is $FOO
  62. # A: yes. FOO did not change outside the function.
  63. #
  64. # Commentary. This seems like a "safe" way to
  65. # lmit namespace pollution and side-effects in bash,
  66. # as long as you don't find the fork/exec overhead.
  67. #
  68. # Figure how EXPORT works/when needed.
  69. #
  70. # inital state: FOO unbound
  71. unset FOO
  72. set -u
  73. echo $FOO
  74. #bash: FOO: unbound variable
  75. # FOO set to bar
  76. FOO=bar
  77. #
  78. function f { echo FOO is $FOO; }
  79. f
  80. #FOO is bar
  81. function g { (echo FOO in subprocess is$FOO) }
  82. g
  83. #FOO in subprocess isbar
  84. FOO=foo
  85. f
  86. #FOO is foo
  87. g
  88. #FOO in subprocess isfoo
  89. cat <<EOF
  90. #! /bin/bash
  91. set -u
  92. echo in h FOO is $FOO
  93. EOF
  94. chmod +x h
  95. unalias h
  96. ./h
  97. #./h: line 3: FOO: unbound variable
  98. export FOO=qux
  99. ./h
  100. # in h FOO is qux