37

I defined some environment variables in my .profile like this:

MY_HOME="/home/my_user"

but the variable does not seem to evaluate unless I strip off the quotes and re-source the file. I believe the quotes are necessary if there will be spaces, and single quotes are used if escapes are not desired. Can someone clarify the significance of single and double quotes in variable definitions? How about front-ticks and back-ticks?

2 Answers 2

33

I think you're confused about terminology.

An "environment variable" is merely a shell variable that any child processes will inherit.

What you're doing in your example is creating a shell variable. It's not in the environment until you export it:

MY_HOME="/home/my_user"
export MY_HOME

puts a variable named "MY_HOME" in almost all shells (csh, tcsh excepted).

In this particular case, the double-quotes are superfluous. They have no effect. Double-quotes group substrings, but allows whatever shell you use to do variable substitution. Single-quoting groups substrings and prevents substitution. Since your example assignment does not have any variables in it, the double-quotes could have appeared as single-quotes.

V='some substrings grouped together'  # assignment
X="Put $V to make a longer string"    # substitution and then assignment
Y=`date`                              # run command, assign its output
Z='Put $V to make a longer string'    # no substition, simple assignment

Nothing is in the environment until you export it.

24

Shell variables vs. environment variables

MY_HOME="/home/my_user" sets the shell variable called MY_HOME. Shells are programming languages, and have variables (also called parameters). After this assignment, you can use the value of the variable, e.g. with echo "$MY_HOME".

Shell variables are an internal shell concept. When that shell instance terminates, MY_HOME is forgotten. What every program knows about and transmits to its children is environment variables.

Inside the shell, environment variables and shell variables work in very similar ways. What actually happens is that all environment variables that the shell inherits from its parent become shell variables. Conversely, a shell variable that is defined in a shell script will become an environment variable if you export it.

export MY_HOME="/home/my_user"

More details you can skip on first reading

The reason why shell variables don't automatically become environment variables is partly that a script might accidentally use a variable name that's meaningful to a program that it launches, and partly just historical.

Some very old shells required export to be used each time you changed a variable name, but all modern shells keep track of assignments for environment variables, so that the following snippet echoes bar:

myvar=foo
export myvar
myvar=bar
env | grep '^myvar='

Also, some very old shells required separate commands for myvar=foo and export myvar, but all modern shells understand export myvar=foo.

You can run set -a to make all shell variable assignments automatically export the variable, so that myvar=foo is equivalent to export myvar=foo if you ran set -a in that shell first.

On quoting

Quoting is mostly orthogonal. If the value you're assigning to the variable doesn't contain any characters that are special to the shell, you don't need any quotes. If there are special characters, you need to protect them with single quotes or double quotes or backslashes or a combination thereof. This goes for both the plain myvar=value syntax and the export utility.

There is one difference between the assignment syntax and the export syntax. The shell expands the results of variable substitutions $foo further, performing field (word) splitting and pathname expansion (globbing). This means that if the value of myvar is hello ​ *, then echo $myvar prints hello followed by a single space followed by the list of files in the current directory. This is almost never desirable, hence the general principle to always use double quotes around variable substitutions (unless you know that you need pathname expansion or field splitting): echo "$myvar". In the case of a simple assignment, othervar=$myvar in fact reliably copies the value of myvar to othervar, because globbing and word splitting are inhibited in assignments (because they create multiple words, but a single word is expected). This dispensation does not apply to export, however. So if you want to remember a simple rule, just always use double quotes around variable substitutions.

2
  • Can you please explain "Quoting is mostly orthogonal." in the section "On quoting"? I don't get the meaning of orthogonal in that sentence.
    – DK Bose
    Mar 11, 2014 at 6:48
  • 2
    @DKBose It means that environment vs shell variables on the one hand, and quoting on the other hand, are two separate issues that have little to do with each other. Wiktionary meanings 4 and 5. Mar 11, 2014 at 9:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .