Episode: 2807 Title: HPR2807: Are bash local variables local? Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2807/hpr2807.mp3 Transcribed: 2025-10-19 17:03:20 --- This in HPR episode 2008-107 entitled Armasch Local Variables Local and is part of the series Bash Crypting. It is hosted by Clacket and in about 11 minutes long and Karimaklin flag. The summary is a lesson on dynamic cope vs lexicals cope. This episode of HPR is brought to you by an honesthost.com. Get 15% discount on all shared hosting with the offer code HPR15. That's HPR15. Better web hosting that's honest and fair at an honesthost.com. Hi, I'm Clacket. In HPR2739, Dave talked briefly about local variables. But what are local variables in Bash? In most modern languages, especially in compile languages, local means that the value of a variable cannot be directly known by looking up the name outside the bound so that function. But that's not how it works in Bash. Languages like CMPython have lexical scope. Lexical scope means local variables are local in the text that was lexical means. The names are local to the function. If I'm writing code that is textually located outside the function, I cannot even describe how to access the variables within the function because the name my variable in my function is not the same variable, not the same place as the name my variable in your function. On the other hand, languages like Bash and Elisp have dynamic scope. That means local variables are local in time. The names are global. So what happens when you declare a variable local in Bash is that the existing value of that variable is stowed away to be brought back when your function exits. So to illustrate this, I've written a short code example. I won't try to say every parenthesis and square bracket here if you want to read the code it's in the show notes. First we have the function say scope that just contains echo. The scope is dollar whatsmascope. So we have a variable whatsmascope that we're going to play with. We have the function global scope that sets that variable to the text global. We have the function dynamic scope that sets the value of the variable to the text dynamic. And then we have the function local scope that declares whatsmascope local, sets the value to local, then calls say scope, then calls dynamic scope and then calls say scope again. So when we run this, we will get the following output. First we run global scope that sets the variable to the text global and then we run say scope and it prints the scope is global. And then we call local scope. So it starts with declaring whatsmascope local and sets the value to the string local and then it calls say scope. Because we have dynamic scope, say scope will see this value and print out the scope is local. We call dynamic scope which will change the value of the variable and because it was declared local in local scope but it wasn't declared local in dynamic scope. When we then run say scope it says the scope is dynamic. And then the function local scope finishes and then we call say scope from the top level and it says the scope is global. So when local scope finished the variable got back the value it had before local scope was called. Maybe it's not clear how this is different unless you see a concrete example also of what the lexicaly local variable means. So we find some language that has both dynamic scope and lexical scope and looks a bit like bash and that's pearl. Pearl has the local keyword that creates dynamic scope for a variable and it has the my keyword that creates lexical scope for a variable. So here's a pearl script. We start with use v5.10 because I want to use the statement say and then we have say scope again. It does say dynamic scope is dolawatsmuscope and then we have the sub global scope. It sets the variable to the text global. We have dynamic scope. It sets the variable to the text dynamic and then we have the new sub lexical scope. It declares a lexical variable with my dolawatsmuscope equals the string lexical. And then because this variable is now a lexically local variable if we would call say scope here it wouldn't see our local value. So we have a line in the sub lexical scope say lexical scope is dolawatsmuscope that will capture our local value and then we call say scope within the sub lexical scope and then we have the sub local scope which is similar to our bash example but we will get lexical scope in there also to see the full interaction between these two features. So local scope declares a local that is a dynamic variable what's muscope sets the values a local calls say scope runs dynamic scope to change the value and then calls say scope again and then it calls lexical scope which as I just described sets a lexical variable prints its value and then calls say scope. So let's see what happens we call global scope and then we call say scope and we get a output dynamic scope is global and then we call local scope it trades this dynamic scope and then sets it to the string local it calls say scope and say scope prints dynamic scope is local then we call the function dynamic scope and then we call say scope again and it says dynamic scope is dynamic and then we call lexical scope lexical scope again creates a local variable within the lexical scope function and then prints lexical scope is lexical and that's the the string value we gave to this lexically local variable and then it calls say scope and say scope prints out dynamic scope is dynamic because we are still within the execution of the subroutine local scope because that called lexical scope so lexical scope exits local scope exits and then we call say scope again and we get dynamic scope is global. The original value of the variable before we call local scope has been restored. That was a whole bunch of stuff you can look at the source code and the output in the show notes. You almost never want to use local in pearl. In fact you have no choice but in pearl since pearl 5 you have the my key weren't to create a lexically local variable which is much more according to what people would expect when they say there's a local variable. There are reasons to use dynamically scope variables. Pearl still has them as we saw and there's a link in the show notes to describe certain situations where it is actually useful. Commonly spent scheme have them also. Commonly spits in the common list standard they have special variables and they usually name them this is just a convention. Name them asterisk some name asterisk to distinguish them from normal variables. In scheme if your scheme implements SRA 539 or R7RS the seventh version of scheme which includes asterisk 539 or if you use racket there's a thing called parameters which are a kind of way to implement dynamic scope in scheme. In common list been scheme these are used for things similar to standard in and standard out and global state like that that you might want to change for some duration of your program when calling some part of the program or to run tests or something. There's more to say about the history of dynamic and lexical scope but that's going to have to be left to another episode of hacker public radio. I've been listening to HackerPublic Radio at HackerPublicRadio.org. We are a community podcast network that releases shows every weekday Monday through Friday. Today's show, like all our shows, was contributed by an HPR listener like yourself. If you ever thought of recording a podcast and clicking our contribute link to find out how easy it really is. HackerPublic Radio was founded by the Digital Dog Pound and the Infonomicon Computer Club, and is part of the Binary Revolution at binwrap.com. If you have comments on today's show, please email the host directly. Leave a comment on the website or record a follow-up episode yourself. Unless otherwise stated, today's show is released under a Creative Commons Introduction. Share like 3.0 live it. BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM BAM