Export an env variable to be available at all sub shells, and possible to be modified?

A copy of the environment propagates to sub-shells, so this works:

$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200

but since it's a copy, you can't get that value up to the parent shell — not by changing the environment, at least.

It sounds like you actually want to go a step further, which is to make something which acts like a global variable, shared by "sibling" shells initiated separately from the parent — like your new tab in Gnome Terminal.

Mostly, the answer is "you can't, because environment variables don't work that way". However, there's another answer, which is, well, you can always hack something up. One approach would be to write the value of the variable to a file, like ~/.myvar, and then include that in ~/.bashrc. Then, each new shell will start with the value read from that file.

You could go a step further — make ~/.myvar be in the format MYVAR=200, and then set PROMPT_COMMAND=source ~/.myvar, which would cause the value to be re-read every time you get a new prompt. It's still not quite a shared global variable, but it's starting to act like it. It won't activate until a prompt comes back, though, which depending on what you're trying to do could be a serious limitation.

And then, of course, the next thing is to automatically write changes to ~/.myvar. That gets a little more complicated, and I'm going to stop at this point, because really, environment variables were not meant to be an inter-shell communication mechanism, and it's better to just find another way to do it.


Suppose I have export MY_VAR=0 in ~/.bashrc.

That's your mistake right there. You should define your environment variables in ~/.profile, which is read when you log in. ~/.bashrc is read each time you start a shell; when you start the inner shell, it overrides MY_VAR. If you hadn't done that, your environment variable would propagate downwards.

For more information on ~/.bashrc vs ~/.profile, see my previous posts on this topic.

Note that upward propagation (getting a modified value from the subshell automatically reflected in the parent shell) is not possible, full stop.


Fish shell can do this with:

set -U MY_VAR 0

(see http://fishshell.com/docs/current/commands.html#set)

To execute a fish command from another shell you can run fish -c, e.g. :

fish -c "set -u MY_VAR 0"