For example, if I make a parameter expansion:

$ b=1
$ echo $b

Where is b stored internally? I checked and it is not an environment variable because it is not listed by printenv. I'm writing my own shell to learn Unix and I used a hashtable to store and retrieve variable as a "symbol lookup table" - is that method a good method or would you suggest me some other way?

  • 1
    It is an environment variable, it just doesn't get passed to subprocesses like env because it's not exported.
    – Kevin
    May 23 '16 at 22:10
  • @Kevin Is it possible to do that in C code? I know how I set an environment variable in C but I don't know how to make the difference between exporter and not exporter variables.
    – Niklas R.
    May 29 '16 at 8:50
  • Kevin: No; if it’s not exported, it’s not an environment variable.
    – Scott
    Jul 27 '18 at 15:00
  • Related: Where are shell functions stored on Linux?
    – Scott
    Jul 27 '18 at 15:00

The shell being run when you log in to read your commands and run them keeps all the variables. If you run a 2nd shell, then it will have its own collection of variables. You can run the set command to see a list of the variables. The set command runs inside the shell instead of launching a new process.

Environment variables are either kept in a separate space or flagged as such (if it matters, then read the shell source code) so they are passed along the programs being run by the shell.

Using two hashtables seems reasonable to me.


It's only a variable for the duration of the program's execution. Another way of thinking about this is by rewriting your program to the following.

echo $b

Now, imagine you're doing that within a terminal, then exiting that terminal session. Opening another terminal session won't show you anything regarding that b=1 assignment in the previous session.

This is called a "local variable", as opposed to a "global variable". They are displayed, along with many other functions, using set.

So, if you want to see the assignment, do

set |grep '^b='


Please see The Linux Documentation Project for more information.


Shell variables are stored in the memory of the running shell. Use any data structure that lets you easily look up an item given its name; a hash table is a good choice.

The difference between shell variables and environment variables is that environment variables are placed in the environment of subprocesses. All environment variables are shell variables. The natural way to store them is to make a hash table that maps variable names not to a value, but to a structure containing a value and some flags (exported, read-only, …).

  • 1
    It's not about subprocesses, but about commands being executed. The memory is duplicated in subprocesses, but wiped when a process executes a command. Environment variables are a list of strings passed alongside the execution that provides with a mechanism to preserve information across that execution. Jul 27 '18 at 14:27
  • 1
    Not all environment variables are shell variables. Environment variables can have arbitrary names (except that they can't contain NUL and = characters) while in most shells, environment variable names have much stricter restrictions. See also the _ special environment variable passed by some shells which is different from the $_ shell variable. Jul 27 '18 at 14:29

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.