3

A trivial situation - the script has finished it's execution, and all the variables used on it's way remained. I'm looking for a way the script could unset all used by it variables ONLY, as there are many other scripts setting their stuff... 'exec bash' is not an option. EG from my imagination:

function setVariables { 
 A="~/"
 B=$(du -sh /smth)
 C="tralala"
}
setVariables

function cleanup {
 readarray -t args < <(setVariables)
 set -u "${args[@]}"
}
cleanup

How to achieve this?

3
  • 1
    When the script ends, the allocated memory becomes free again. Commented Nov 28, 2017 at 19:12
  • 2
    If you can run your script in a subshell, its variables will be isolated, will not propagate to parent shell, and you don't have to unset them.. Commented Nov 28, 2017 at 19:24
  • You could put all your code in a function and declare variables as local. They will then drop out of scope (destroyed) at the end of the function. Commented Nov 28, 2017 at 20:46

1 Answer 1

3

Like already suggested in comments, the trivial solution is to put the commands in a script instead of in a function. The script runs in a subprocess with its own environment, and doesn't change anything in the parent. When the child finishes, nothing from its environment is left.

If you need to use a function, Bash has a local keyword which makes the variable's scope local to the current function. When the function ends, all variables are reset to their state from before the function ran (unset if they were unset, previous value if they were set).

If you want to set variables and have them set outside of a function, but have a simple way to revert them to their original value, you really have to build that yourself. Look at how Python's virtualenv does it, for example (a common and popular example, though not necessarily the absolutely most robust) -- it basically writes out the previous values to the definition of the deactivate command which disables the virtual environment and (attempts to) return things to the way they were before you ran activate.

# bash 4+ only!
setVariables () { 
   declare -A _setvariables_old=([A]="$A" [B]="$B" [C]="$C")
   A="~/"
   B=$(du -sh /smth)
   C="tralala"
}
setVariables
:
cleanup () {
   local var
   for var in "${!_setvariables_old[@]}"; do
       printf -v "$var" "%s" "${_setvariables_old[$var]}"
   done
   unset _setvariables_old
}

This leaks slightly (what if _setvariables_old is a variable you want to preserve!?) and doesn't know how to unset things; it just reverts to an empty string if something was unset before you started.

Sign up to request clarification or add additional context in comments.

6 Comments

Untested for now, but you get the idea I hope
Thanks a lot to all for the comprehensive explanation. @tripleee: I cannot put all my commands in the body of a script, as there are too many of them and it hits the performance. Could you please elaborate regarding the 'local' variables. I have few functions inside a single script. Each function has its own set of variables, that become declared once the function is called. Aren't all the vars in this flow considered to be 'local'?
I'm not sure I understand any of the several apparent points in your comment. How does putting commands in a script affect their performance, regardless of how many there are? In f () { local a; a="foo"; b="bar"; } the value of a inside the function is unavailable outside the function, whereas the value of the global variable b is available to the entire rest of the script, and gets set to "bar" when you call the function.
in my case all the variables are results of heavy calculations that (for example) compare free space on one drive to the size of another. And many other in this vein. They all are dynamic, and relevant only per query by certain function.
And putting them in a script makes them slower because ...?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.