I have been trying to understand shell scopes and environment in depth. I have been reading about how if we do export VARIABLE=VALUE it will be available in subshell. So I wanted to ask a question I had in mind.

If I understand right, if we execute a binary program by a script file, it will be able to see environment variables because, environment variables that are set through terminal in linux( let's say debian ) are visible to all programs run by a script file.

So my question and confusion is, whether there is a shell that is the parent of all. I am kinda confused about hierarchy. When I open terminal in debian, and type export VARIABLE=VALUE, is this going to be visible to all script files, even if I run them by double clicking at the desktop ?

I hope my question is not vague and suitable for serverfault.

  • Very interesting question.
    – Suraj Jain
    Apr 13 '20 at 15:15

All processes - be they a shell or otherwise - form a hierarchy. Environment variables are handed down from parent to child process, unless the parent takes explicit action to manage the child's environment. In most systems init is the process at the root of the process tree, but the situation may differ, for example in embedded environments. Running pstree -a shows you all processes in a tree.

Environment variables set by child processes are neither propagated to parents nor siblings, so that exporting a variable in a terminal window will only affect processes started from within that window. Thus the answer to your question is no.

  • But then, how is it possible that I set "export JAVA_HOME=..." through standard terminal, and every script I start by double clicking is able to see that environment variable ?
    – Ozum Safa
    Mar 11 '15 at 14:57
  • 1
    Are you really sure it is? JAVA_HOME might be defined elsewhere like any of the xsessionrcvariants.
    – hennejg
    Mar 11 '15 at 15:34
  • So basically to make environment variable global and persistent, you have to define them in /etc/profile or /etc/bashrc . But then, what if I have to set a global env variable for JAVA_HOME, for it to be valid for everything I start in my linux system ? Would /etc/profile be enough for that ?
    – Ozum Safa
    Mar 11 '15 at 15:35
  • 1
    Yes, in general, /etc/profile should work, although from a maintainability perspective I'd strongly recommend placing a script into /etc/profile.d e.g. /etc/profile.d/java-home.sh and exporting the variable there.
    – hennejg
    Mar 12 '15 at 7:32
  • @hennejg: At the risk of splitting hairs, environment variables are handed down from parent to child, always. A child process's evnironment is the same as its parent's unless the parent takes explicit action to pass the child a different environment. Also, a running program can change its own environment.
    – Scott
    Mar 13 '15 at 18:06

In so many words; no, a shell you run as a child of your X11 session has no way to change the environment of the X11 session, which is going to be the parent (or possibly grandparent) of processes you start by double-clicking on the desktop.

A common workaround is to write the double-clickable tool in such a manner as to connect to some sort of configuration mechanism and fetch the settings it needs. This could be just a configuration file in your home directory, or some kind of settings daemon. Modern X11 desktop environments are running these things out of the box; maybe start by looking at dbus.

Of course, this only helps for tools which are designed to run exclusively in an environment where these facilities are available. In the general case, you might want to have your Java program read a system-wide configuration file, something like /etc/eat_memory_and_crash.conf (assuming your Java program is called eat_memory_and_crash; though within the Java ecosystem, I suppose this would be an XML file).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.