Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is unsetting global variables defined in a script good practice?

Tags:

bash

sh

Is it considered good practice, when writing sh scripts, to unset all previously defined global variables at the end of the script?

If for example, I execute my script myscript using the . (source) builtin, like this

. myscript

after executing the script the shell is poluted with the variables defined in the script. This seems really bad (especially if used by other people).

If I could, I would get rid of globals in sh (or bash) altogether but more often then not they are the least worst solution :-).

like image 376
helpermethod Avatar asked Dec 11 '22 21:12

helpermethod


2 Answers

This isn't really executing the script. It is sourcing it, which makes the shell execute each command inside the script. If you want to execute the script, you would do this:

./myscript

And in that case, none of the environment variables that are set inside the script would have an effect on your shell.

If you really need to source the script, so that it can do things like set environment variables or change your current directory, then you can isolate the variables inside a sub-shell using parentheses:

(
  a=7
  echo $a
)
# The change in a doesn't get to here

If you were to unset the variables you use, you would have the opposite problem. If a variable with the same name had been set by the user, then you would end up destroying it.

like image 150
Vaughn Cato Avatar answered Dec 29 '22 00:12

Vaughn Cato


Is it considered good practice, when writing sh scripts, to unset all previously defined global variables at the end of the script?

If the script is executed normally (in a sub-shell, using myscript), then there is no reason to worry about variables (or functions) defined in the script; they vanish when the script stops executing with no damage done to the calling shell.

If for example, I execute my script myscript using the . (source) builtin, like this

. myscript

after executing the script the shell is polluted with the variables defined in the script. This seems really bad (especially if used by other people).

Any script that is sourced needs to have a very good reason to be sourced at all (setting specific environment variables or changing directory are the usual reasons). Any such script that is going to be used by other people should be fanatic about unsetting any variables it sets incidentally, being careful to use distinctively named variables in the first place and unsetting them all as it completes.

Or, at least, I won't source someone else's script if it litters my shell with variables. I don't often source files outside of 'profile' operations, but when I do, the script is designed to set certain variables. It can set those (it wouldn't be useful if it didn't); but it had better not add a random assortment of other variables. If necessary, I make a copy of the other person's script and sanitize it for my own use, or wrap it with a sanitizing script.

I have a script that I use for setting PATH (so it more or less has to be sourced to be useful). It starts:

ps_machine=$(uname -n)
ps_pathset=no
ps_pathoptsfile=
for ps_file in \
        ${HOME}/.pathopts.$ps_machine \
        ${REAL_HOME:-$HOME}/.pathopts.$ps_machine \
        ${HOME}/.pathopts \
        ${REAL_HOME:-$HOME}/.pathopts
do
    ...40 lines of esoteric code...
    ...some set ps_perl; some set ps_pathopts...
done

...5 lines of active code that set PATH...

unset ps_pathset ps_pathoptsfile ps_pathopts ps_file ps_perl ps_machine

I invoke this as:

. mcpathset

An alternative design for this command would be:

export PATH=$(mcpathset)

Here, the output of the command is used as the new value for the PATH. When you only need to set a single variable, this is a viable design. If you need to set a suite of environment variables (to configure the environment to use a particular DBMS, for example), this is less feasible.

I don't do the cleanup of variables with normal scripts — ones that are not intended to be sourced. But for source-able scripts, I think it is important. I doubt that everyone agrees with me; many people probably couldn't care less. But I agree with you — it is important for sourced scripts to be clean.

like image 25
Jonathan Leffler Avatar answered Dec 29 '22 00:12

Jonathan Leffler