4

Consider the following code:

#!/usr/bin/bash

t_export() {
  declare dummy="Hello"
  export dummy
  echo dummy: $dummy
  echo printenv dummy: $(printenv dummy)
}

t_export
echo dummy: $dummy
echo printenv dummy: $(printenv dummy)

Output:

dummy: Hello
printenv dummy: Hello
dummy:
printenv dummy:

How do you explain this? I thought the environment is always global and therefore the variable dummy would also be visible outside the function.

Roland
  • 7,525
  • 13
  • 61
  • 124

2 Answers2

8

export doesn't copy values in to the current environment. Instead, it sets the export attribute on a name. When a new processes is started, any variables marked with that attribute are copied (along with their current values) into the environment of the new process.

When t_export returns, the variable dummy goes out of scope, which means it is no longer available to be exported to new processes.

chepner
  • 497,756
  • 71
  • 530
  • 681
5

declare inside a functions defaults to local. Use -g to declare a global from inside a function.

choroba
  • 231,213
  • 25
  • 204
  • 289
  • I understood that it is local. But after export it should be in the environment, no? Apparently it is removed from the environment once you leave the function? – Roland Jul 26 '21 at 12:41
  • 1
    `export` has nothing to do with global variables. It marks a *name* to be copied into the environment of a new child process. It doesn't immediately copy the variable into the *current* environment. – chepner Jul 26 '21 at 12:43
  • @chepner apparently it does, see the `printenv` inside the function. – Roland Jul 26 '21 at 12:46
  • 1
    Yes, when `printenv` (or more precisely, the process to execute the subshell that starts `printenv`), the values of any current variables marked as exported are copied into the new process. They don't actually exist in the environment of the current process. (It's a subtle distinction, and one that is hard to confirm directly because the shell doesn't provide a way to examine its own environment, but you are seeing the evidence by `dummy` no longer existing when you run `printenv` *after* `t_export` returns.) – chepner Jul 26 '21 at 12:49
  • 1
    If you have a `proc` filesystem, you can see that an exported variable does not appear in `/proc/$$/environ`. – chepner Jul 26 '21 at 12:51