39

What are the differences between shell and environment variables? Where are these variables stored?

codeforester
  • 39,467
  • 16
  • 112
  • 140
sunil
  • 751
  • 1
  • 8
  • 9

5 Answers5

33

Citing this source,

Standard UNIX variables are split into two categories, environment variables and shell variables. In broad terms, shell variables apply only to the current instance of the shell and are used to set short-term working conditions; environment variables have a farther reaching significance, and those set at login are valid for the duration of the session. By convention, environment variables have UPPER CASE and shell variables have lower case names.

To list all environment variables, use printenv and to list all shell variables, use set.

You'll note that the environment variables store more permanent value, e.g.:

HOME=/home/adam

Which changes quite seldom, while the shell variables stores local, temporary, shell-specific values, e.g.:

PWD=/tmp

which changes every time you change your current directory.

For most practical tasks, set environment values by adding export VARIABLE_NAME=VALUE to your ~/.bashrc file.

Adam Matan
  • 128,757
  • 147
  • 397
  • 562
  • environment variable are user defined ? & shell variable s are system define ? also u had mentioned the commands not the location i means where the variable are located ??? – sunil Jul 27 '10 at 07:35
  • What do you mean by 'Where the variables are located'? Where do you set their value, or where are the (technically) stored in the computer's memory? – Adam Matan Jul 27 '10 at 08:59
  • any file is there where they are stored && are they userdefined or predefined – sunil Jul 27 '10 at 10:15
  • when we use set or env command from where the output is called from(i mean whatz the designation file or memory ) – sunil Jul 27 '10 at 10:19
  • 1
    You quoted "By convention, environment variables have UPPER CASE and shell variables have lower case names.", but you were showing us that upper case are used for for both shell and environment variables. – zell Feb 05 '16 at 03:47
  • 3
    To provide a more canonically correct source, see the *Environment Variables* section of the POSIX specification at https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html. Uppercase is used for variables -- either exported or otherwise -- that can modify the behavior of the shell and of POSIX-specified tools; whereas lowercase should be used for variables, **including environment variables**, that are application-defined and not expected to modify POSIX-specified tool behavior. – Charles Duffy Mar 10 '20 at 15:24
  • @zell, see above. By POSIX spec, uppercase is used for variables that reflect or modify shell and POSIX-specified tool behavior, whereas names with at least one lowercase character are reserved for application-defined use. – Charles Duffy Mar 10 '20 at 15:25
17

For Bash shell:

Shell variables differ from environment variables in different ways:

♦ A shell variable is specific to the shell itself and is not inherited by child processes. For example, let's say you're running another application from the shell, that application will not inherit the shell variable:

$ SHELL_VAR=xyz
$ firefox

SHELL_VAR will not be available in the environment of the child process (firefox).

♦ In contrast, environment variables of the parent process (the shell here) are inherited by all child processes:

$ export SHELL_VAR=xyz
$ firefox

♦ Both shell and environment variables are local to the shell/process which defined them:

Environment variables can be persistent, whereas, for shell variables once you exit the session, they're all gone.

Note: the above examples only alter the shell that you're working on, in other words, if you logout or start a new shell/terminal you're not going to see the variables that you defined, this is per the principle of process locality.


How to make presistent shell variables:

One way to do that is by modifying the ~/.profile file:

export SHELL_VAR=xyz

This setting is user-specific and not system-wide, for system-wide environment variables, you can add the above line to a .sh file in /etc/profile.d

I highly recommend reading this page: EnvironmentVariables

jmrah
  • 5,715
  • 3
  • 30
  • 37
GIZ
  • 4,409
  • 1
  • 24
  • 43
  • 1
    Fair to say then that 'persistent' environment variables are in no way actually different to an exported shell variable. The only difference is in where they are stored. Persistent ones are written to (and then read) from non-volatile media (i.e. disk). This is in a location (i.e. ~/.profile) that is automatically read when the shell is loaded. An exported shell variable is identical, except it exists only in volatile memory and is therefore lost on a reboot (power loss, etc). Is that correct? – Chris Aug 16 '20 at 05:53
15

Their difference is similar to the difference between private fields and protected fields in a Java class.

The private fields of a Java class is only accessible from that Java class. The protected fields of a Java class is accessible from both that Java class and its subclasses.

The shell variables of a shell is only accessible from that shell process. The environment variables exported from that shell is accessible from both that shell process and the sub-processes created from that shell.

twimo
  • 4,061
  • 5
  • 29
  • 32
0

In addition to the information in the other answers, environment variables are not as flexible as shell variables.

Shell variables can be arrays or associative arrays, but environment variables can only be strings. The environment that's inherited by child processes is simply a sequence of name=value strings. There's no parsing of the values, so no way to indicate that a value should be an array.

Barmar
  • 741,623
  • 53
  • 500
  • 612
-2

A shell variable is just a special case of an environment variable. shell variables are inherited from the environment and possibly copied to the environment of children of the shell depending on syntax used: http://www.pixelbeat.org/docs/env.html

pixelbeat
  • 30,615
  • 9
  • 51
  • 60
  • 3
    This is not correct. You basically have the terms reversed. Obviously there is a lot of confusion on this topic, even by veteran users and a coreutils dev? :-/ – deltaray Oct 25 '11 at 23:03
  • 2
    I don't think I've reversed the terms. I was implying that the environment list is more fundamental and present for all processes including shells. shell variables are a special case that are initialised _from_ the environment list – pixelbeat Apr 16 '12 at 07:52
  • But you can create shell variables that aren't environment variables. When you do `foo=bar` it creates a shell variable. It becomes an environment variable when you do `export foo`. – Barmar Aug 24 '23 at 22:56