i devised simple test see how bash behaves recursion, , not understand results.
test:
- assign global variable
x
in shell - create function
f()
assigns variablelocal x
of same name - assign
local x
value of globalx
i.e.local x=$x
- recurse function few times , check whether, on each recursion, uses global
x
orlocal x
previous turn of function
i expected 1 of 2 outcomes:
- on each recursion,
local x
previousf()
new "global"x
, i.e.x
in next-up scope, indicate each recursion creates new scope beneath previous scope - on each recursion, previous
local x
value forgotten, , each newlocal x=$x
reassign value of globalx
assigned. indicate bash creates adjacent scopes.
i didn't of these. got weird. below copy-paste terminal.
i assign global variable in shell:
user@ubuntu-zesty:~$ x=1
i create function f()
in shell creates local x
, assigns value of global x
it, enters while loop, adds 1 local x
(i assume local one), prints new local x
value, , calls itself. repeat 5 or 6 times.
user@ubuntu-zesty:~$ f() { local x=$x; while [ $x -lt 6 ]; x=$(( $x + 1 )); echo $x; sleep 1; f; done; }
then call f()
, , output baffling.
user@ubuntu-zesty:~$ f 2 3 4 5 6 6 5 6 6 4 5 6 6 5 6 6 3 4 5 6 6 5 6 6 4 5 6 6 5 6 6
at point exited on own. , expected global x
unaffected.
user@ubuntu-zesty:~$ echo $x 1
so what's going on here? using global x
, local x
? please if know what's going on here don't spare me gory details.
lastly, fun, graph of output:
1 == 2 === 3 ==== 4 ===== 5 ====== 6 ====== 7 ===== 8 ====== 9 ====== 10 ==== 11 ===== 12 ====== 13 ====== 14 ===== 15 ====== 16 ====== 17 === 18 ==== 19 ===== 20 ====== 21 ====== 22 ===== 23 ====== 24 ====== 25 ==== 26 ===== 27 ====== 28 ====== 29 ===== 30 ====== 31 ======
specs:
- bash-4.4.5(1)-release
- x86_64 ubuntu zesty
- linux kernel 4.10.0-17-generic
- vmware workstation 12 virtual machine
i think best way visualize dynamic scoping explained @chepner in answer modify function slightly:
function f() { local x="$x" while [ "$x" -lt 6 ]; x=$((x + 1)) echo "${funcname[*]}" "$x" # print call stack sleep 1 f done }
and see how values increase: if follow output columns, can debug happens @ each level.
$ f f f f f f 2 f f f f f f 3 f f f f f f f 4 f f f f f f f f 5 f f f f f f f f f 6 f f f f f f f f 6 f f f f f f f 5 f f f f f f f f 6 f f f f f f f 6 f f f f f f 4 f f f f f f f 5 f f f f f f f f 6 ...
Comments
Post a Comment