Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am using Red Hat Linux Enterprise 5. I know the theory that -- using export to set environment variable, the environment variable will apply to current and child environment, but without using export to set environment variable, the environment variable will only apply to the current environment.

My confusion is, what is the exact definition of "child environment" and "current environment"? For example,

$ var1=123
$ echo "Hello [$var1]"

the value of var1 (which is 123) is printed in shell, but I think echo is a command invoked by current shell, and it (the echo command) should be a child environment of current shell and the value of var1 should not (because not using export var1=123) impact echo. Any comments?

Thanks in advance!

share|improve this question

1 Answer 1

up vote 3 down vote accepted

The variable is expanded in the current environment.

$ set -x    # turn on tracing
$ var1=123
+ var1=123
$ echo "Hello [$var1]"
+ echo 'Hello [123]'
Hello [123]
$ set +x

As you can see from the trace (the lines beginning with "+"), echo sees "Hello [123]". It never gets the variable.

As you saw from gogiel's answer to your other question, exported environment variables do affect the environment of the child:

$ echo $LANG
en_US.UTF-8
$ declare -p LANG   # the response includes "-x" which shows the variable is already marked for export
declare -x LANG="en_US.UTF-8"
$ ls --help | head -n 4
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort.
$ LANG=es_MX.utf8 ls --help | head -n 4
Uso: ls [OPCIÓN]... [FICHERO]...
Muestra información acerca de los ARCHIVOS (del directorio actual por defecto).
Ordena las entradas alfabéticamente si no se especifica ninguna de las opciones -cftuSUX ni --sort.

Or I could have set the value of LANG in the current environment and since it's exported it would be inherited by the child environment:

$ LANG=es_MX.utf8
$ grep --help | head -n 4
Modo de empleo: grep [OPCIÓN]... PATRÓN [FICHERO]...
Busca un PATRÓN en algún ARCHIVO o entrada estándar.
PATTERN es, por omisión, una expresión regular básica (BRE).
Ejemplo: grep -i '¡Hola, mundo!' menu.h main.c
$ sed --help | head -n 4
Uso: sed [OPCIÓN]... {guión-sólo-si-no-hay-otro-guión} [fichero-entrada]...

  -n, --quiet, --silent
                 suprime la muestra automática del espacio de patrones
$ while [[ = 4 ]]    # create an error on purpose to show Spanish error message
bash: se esperaba un operador binario condicional
bash: error sintáctico cerca de `4'

Edit:

Here is a simple script (let's call it showvars) so you can see what's going on both inside and outside.

#!/bin/bash
arguments="$@"
printf "The script has started.\n"
printf "These are the parameters passed to the script: [$arguments]\n"
scriptvar=100
printf "This is the value of scriptvar: [$scriptvar]\n"
printf "This is the value of exportvar: [$exportvar]\n"
printf "This is the value of shellvar: [$shellvar]\n"
printf "This is the value of commandvar: [$commandvar]\n"
printf "The script has ended.\n"

Now we do these steps at a shell prompt:

$ shellvar=200
$ export exportvar=300
$ ./showvars 400 $shellvar 500
The script has started.
These are the parameters passed to the script: [400 200 500]
This is the value of scriptvar: [100]
This is the value of exportvar: [300]
This is the value of shellvar: []
This is the value of commandvar: []
The script has ended.
$ commandvar=600 ./showvars 400 $shellvar 500
The script has started.
These are the parameters passed to the script: [400 200 500]
This is the value of scriptvar: [100]
This is the value of exportvar: [300]
This is the value of shellvar: []
This is the value of commandvar: [600]
The script has ended.
$ printf "This is the value of commandvar: [$commandvar]\n"
This is the value of commandvar: []
$ commandvar=600
$ ./showvars 400 $shellvar 500
The script has started.
These are the parameters passed to the script: [400 200 500]
This is the value of scriptvar: [100]
This is the value of exportvar: [300]
This is the value of shellvar: []
This is the value of commandvar: []
The script has ended.
$ printf "This is the value of scriptvar: [$scriptvar]\n"
This is the value of scriptvar: []
$ printf "This is the value of exportvar: [$exportvar]\n"
This is the value of exportvar: [300]
$ printf "This is the value of shellvar: [$shellvar]\n"
This is the value of shellvar: [200]
$ printf "This is the value of commandvar: [$commandvar]\n"
This is the value of commandvar: [600]

As you can see shellvar is not available inside the script and scriptvar is not available outside it. Since exportvar is exported, it's available both inside and outside the script. And commandvar is only available inside the script when it's passed on the command line when calling the script. If it's set in the interactive environment and then the script is called, it's available only in the interactive environment.

share|improve this answer
1  
Yes, the variable is expanded by the shell (it replaces the variable with its value) and the value is passed to echo. So echo never sees the variable, just its value. –  Dennis Williamson May 22 '10 at 17:36
1  
@George2: Look at the trace at the top of my answer. The "$" is the shell prompt. I type echo "Hello [$var1]" and the next line (that starts with "+") shows what actually happens. The shell (Bash) tells echo to output "123". The shell replaces the name of the variable with its value before it gives it to echo so echo never sees the variable it only sees the value passed as a parameter. I'm going to add a small script to my answer that will show what's going on by letting you see inside the process. It will take me a few minutes, so check back if it's not there yet. –  Dennis Williamson May 23 '10 at 14:27
1  
@George2: What kind of other entities? mkdir is a child of whatever environment it's invoked from - the interactive shell or a script, for example. Usually such executables are only affected by exported environment variables that are documented in their man pages. The one type of environment variable that is often effective even though it's not documented in individual man pages is the set of locale related variables such as LANG demonstrated in some of the examples above. –  Dennis Williamson May 24 '10 at 3:46
1  
executables, scripts, commands, yes. –  Dennis Williamson May 24 '10 at 11:17
1  
No, not an exception. Look at file="/etc/passwd"; ls -l "$file" Here ls is receiving a variable's value from the parent shell. The value not the variable itself. –  Dennis Williamson May 25 '10 at 8:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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