Score:2

The difference between "echo" and "export" an environment variable?

sa flag

The environment is Ubuntu 18.

If I add one line JAVA_HOME="/usr/java11" in /etc/environment, and execute source /etc/environment , I can echo this environment variable:

echo $JAVA_HOME
/usr/java11

But if I try to get it from export, this variable is not in the list:

export | grep JAVA_HOME
--result is blank--

Then I use export $JAVA_HOME=/usr/java8 to export a variable (notice here is java8, not java 11), I can have:

export |grep JAVA_HOME
declare -x JAVA_HOME="/usr/java8"

Now, I can still echo $JAVA_HOME as /usr/java11:

echo $JAVA_HOME
/usr/java11

Question: what is the difference of echo $variable and export | grep JAVA_HOME?

I try a simple python program, os.environ.get("JAVA_HOME") returns "/usr/java8" from the export, not the echo.

guiverc avatar
cn flag
You mention Ubuntu 18, so is this a *contained* Ubuntu Core 18 or *snap* only environment? as the *confinement* models in play in 18 releases differ to the more open 18.04 models - please be specific.
hr flag
I think the issue here is that `/etc/environment` is just a list of name=value pairs. When it is read by `pam_env` those variables are exported to the environment, but sourcing it into your current shell only creates ordinary shell variables - check with `declare -p JAVA_HOME` for example.
Ben L avatar
sa flag
@steeldriver , what is "ordinary shell variables", and what are other variables?
Ben L avatar
sa flag
@guiverc sorry I don't know what is 'contained' and what is 'snap'. It is a docker container created from 'FROM ubuntu:18.04'
guiverc avatar
cn flag
Ubuntu 18.04 is a different product to the 18 products; Ubuntu normal *deb* based releases (without containment) use the *year.month* format; differing from the 18 or *year* based products that use containment. Ubuntu has had *year* based products since 2016 - you should be precise as 18 & 18.04 represent different products (a 18 release cannot use a *deb* package - it's *snap* only) fyi: *confinement* models can vary on snap; but if you're familiar with containers you ~know this; it's the ~same with different terminology..
vanadium avatar
cn flag
Does this answer your question? [What's the difference between set, export and env and when should I use each?](https://askubuntu.com/questions/205688/whats-the-difference-between-set-export-and-env-and-when-should-i-use-each)
Score:12
hr flag

The issue here is not really the difference between echo and export, but rather the difference between an environment variable and a simple shell variable (and also about how the /etc/environment file is normally used).

In particular, although /etc/environment happens to contain lines of the form name=value that are valid as POSIX shell variable assignments, its primary purpose (in a modern Linux system) is to be read by the pam_env module during initialization of a user's session - it is pam_env that exports them to the user's environment.

When you source /etc/environment into your shell, there's no special magic that tells the shell that the assignments are those of environment variables (which are exported to the environment, and hence inherited by sub-processes) rather than regular shell variables (which are just available in the current shell scope).

Next time you log in, pam_env will do its magic and JAVA_HOME will then appear in the output of export | grep JAVA_HOME.

See also

Ben L avatar
sa flag
Thanks to point out the difference between "shell variable" and "environment variable".
vanadium avatar
cn flag
"environmental variables" technically also are "shell variables". They are a subset.
Score:5
cn flag

echo and export are very different commands in the first place.

  • echo will display text. In echo $JAVA_HOME, the shell will substitute $JAVA_HOME with the contents of the shell variable JAVA_HOME it it is defined. Otherwise, $JAVA_HOME will return an empty string.
  • export provides the "export" attribute to the shell variable. export JAVA_HOME will set the export attribute, i.e., the variable will also be available in the environment of any sub shell or sub process rather than in your current shell only. If the variable is not yet set, you can define it while exporting as in export JAVA_HOME=/usr/java11.

In /etc/environment, environment variables are registered with the syntax of a variable assignment. The content of /etc/environment in a default Ubuntu install indeed can be executed. So if you execute the line you included:

`JAVA_HOME=/usr/java11`

Then, all that will do is assign the shell variable PATH the current value.

However, because you included the variable in /etc/environment, it should be effectively be exported during the next startup of your system. Then, it should exist in export and show up in echo $JAVA_HOME in the first terminal you open. So what you currently observe is because you did not yet restart the machine after modifying /etc/environment (and did not export the variable in other ways).

Score:3
in flag

Building on the other answers here, some commands that parallel export but for other categories of variables are set (which works for e.g. VARIABLE=value then set | grep VARIABLE) and env

Each of these three commands, when given no arguments, prints a list of variables; which variables they will print has to do with the kinds of variables the command manages.

See What's the difference between set, export and env and when should I use each?

echo $VARIABLE always works since all kinds of variables can be read as $VARIABLE; however, this means it gives you no information on what kind of variable it is or where it comes from.

Score:0
us flag

echo is a command for printing text and variables to stdout (or redirect).

export lists the current exported variables in the shell.

This thread explains why you would use export much better than I can:

https://stackoverflow.com/questions/7411455/what-does-export-do-in-shell-programming ... it does a great job explaining what export is fo

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.