| |

LFCS 44 ๐Ÿง Environment Variables โ€” Overview

โฑ๏ธ Estimated read: 10 min | |

Environment variables are the mechanism Linux uses to pass configuration down a process tree. When a program starts, it receives two things from its parent: command-line arguments and an environmentโ€”a set of name-value pairs that tell the program where to find its home directory, which locale to use, where to look for executables, and dozens of other details . The shell is where these variables are usually set and exported, and every process launched from that shell inherits a copy of the environment.

For the LFCS exam, “Use shell/environment variables” is a listed objective in the Essential Commands domain . The distinction that matters most is between a shell variable and an environment variable: a shell variable exists only in the current shell session, while an environment variable is exported and inherited by child processes . Understanding this differenceโ€”and knowing the commands to view, set, export, persist, and unset variablesโ€”is the core of the topic.

Key point: An environment variable is a named value exported from a shell and inherited by all child processes; a shell variable is local to the current shell and is not passed to children. The export command is what turns a shell variable into an environment variable.


Why environment variables exist

The configuration propagation problem. Programs need configuration: where is the user’s home directory, which language should messages be displayed in, which directories contain executables. Hard-coding this into every program would be brittle and unmaintainable. The environment solves this by providing a standard channel: the parent process (usually the shell) sets variables, and every child process reads them. A program does not need to know how HOME was setโ€”it just reads the value from its environment .

The shell vs environment distinction. Not every variable needs to be inherited. A variable used in a single scriptโ€”a loop counter, a temporary pathโ€”should not leak into every subsequent command. Shell variables serve this purpose: they are visible only in the current shell. When a variable must be available to child processes, export marks it for inheritance . This separation keeps the environment clean and prevents accidental leakage of local state.

The persistence problem. Environment variables set with export in a terminal last only until that shell exits. For a variable to survive across sessions, it must be written to a configuration file that the shell reads at startup. The correct file depends on whether the shell is a login shell or an interactive non-login shell, and on the distribution’s conventions . Understanding this is essential for making changes permanent.

The standard variable problem. Some variables are so universally useful that they are defined by convention or by the system itself. PATH tells the shell where to find commands. HOME points to the user’s home directory. USER and LOGNAME identify the current user. SHELL names the shell. PWD is the current working directory. TERM describes the terminal type . Knowing these is not optionalโ€”scripts and programs rely on them.

The inheritance boundary. A child process gets a copy of the environment, not a reference to it. Changes made in a child do not affect the parent. This isolation is deliberate: it prevents one program from corrupting the environment of another, and it makes reasoning about variable scope straightforward .


a. Shell variables vs environment variables

A shell variable is created by assignment and exists only in the current shell. No spaces are allowed around the = sign.

greeting="hello"
echo $greeting

This variable is not visible to child processes. If you run bash to start a subshell and then echo $greeting, it prints nothing. The variable is local to the shell where it was defined .

To make a variable an environment variable, use export:

export greeting="hello"

Now greeting is inherited by any child process. Running bash and then echo $greeting prints hello . You can also export an existing shell variable:

greeting="hello"
export greeting

The export command without arguments lists all exported variables. The set command lists all shell variables, environment variables, and functions. The env and printenv commands list only environment variables .

Variable names are case-sensitive. By convention, environment variables use uppercase names (PATH, HOME, USER) and local script variables use lowercase, though this is style, not rule .


b. Viewing and unsetting variables

The env command prints all environment variables in NAME=value format. printenv does the same, and printenv NAME prints a single variable .

printenv PATH
echo $PATH

The echo approach works for any variable, shell or environment. The $ prefix tells the shell to substitute the variable’s value. Braces are safer when concatenating: ${PATH}:/new/dir avoids ambiguity .

To remove a variable, use unset:

unset greeting

This removes both shell and environment variables from the current session. If the variable is defined in a configuration file, unset removes it only for the current session; it will reappear in the next session unless the configuration file is edited .


c. Persistence and the standard variables

Variables set in a terminal are temporary. To persist them, write the export line to a shell startup file. The correct file depends on the shell type:

  • Login shells (SSH login, console login) read /etc/profile, then ~/.bash_profile, ~/.bash_login, or ~/.profile in that order .
  • Interactive non-login shells (a terminal window in a graphical session) read /etc/bash.bashrc and ~/.bashrc .

A common convention is to put environment variables in ~/.profile or ~/.bash_profile and shell-specific settings (aliases, prompt customization) in ~/.bashrc. Many distributions’ ~/.bash_profile sources ~/.bashrc automatically .

To set a system-wide variable for all users, place it in a file under /etc/profile.d/ with a .sh extension. Files there are sourced by /etc/profile .

The most important standard variables are:

  • PATH: colon-separated list of directories searched for executables. When you type a command without a path, the shell searches these directories in order .
  • HOME: the user’s home directory .
  • USER / LOGNAME: the current username .
  • SHELL: the path to the current shell .
  • PWD / OLDPWD: current and previous working directory .
  • TERM: terminal type .
  • LANG / LC_*: locale and language settings .

Complete Example Session

The following session demonstrates shell variables, environment variables, persistence, and the difference between them.

# ============================================
# PART 1: CREATE A SHELL VARIABLE
# ============================================
greeting="hello from shell"
echo $greeting
# Output: hello from shell

# ============================================
# PART 2: SHELL VARIABLE IS NOT INHERITED
# ============================================
bash -c 'echo $greeting'
# Output: (empty line)
# The child shell does not see the variable

# ============================================
# PART 3: EXPORT THE VARIABLE
# ============================================
export greeting="hello from environment"
bash -c 'echo $greeting'
# Output: hello from environment

# ============================================
# PART 4: VIEW ENVIRONMENT VS SHELL VARIABLES
# ============================================
env | grep greeting
# Output: greeting=hello from environment

# Create a shell variable
localvar="only in this shell"
set | grep localvar
# Output: localvar='only in this shell'

env | grep localvar
# Output: (empty, not an environment variable)

# ============================================
# PART 5: PERSIST A VARIABLE
# ============================================
echo 'export MY_APP_ENV="production"' >> ~/.bashrc
source ~/.bashrc
echo $MY_APP_ENV
# Output: production

# ============================================
# PART 6: UNSET A VARIABLE
# ============================================
unset greeting
echo $greeting
# Output: (empty)

The six parts cover shell variable creation, the inheritance boundary, exporting, viewing the difference between env and set, persistence via ~/.bashrc, and unsetting. What the session demonstrates is that export is the dividing line: without it, a variable is local; with it, the variable is inherited.


Quick Reference

Shell vs Environment Variables

TypeCreated WithInherited by ChildrenVisible In
Shell variablevar=valueNoCurrent shell
Environment variableexport var=valueYesCurrent shell and children

Viewing Commands

CommandShows
envEnvironment variables only
printenvEnvironment variables only
printenv NAMEOne environment variable
setShell variables, environment variables, functions
exportExported variables
echo $NAMEAny variable

Standard Variables

VariableMeaning
PATHExecutable search path
HOMEHome directory
USER / LOGNAMECurrent user
SHELLCurrent shell
PWD / OLDPWDCurrent / previous directory
TERMTerminal type
LANGLocale

Persistence Files

Shell TypeFiles Read
Login shell/etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile
Interactive non-login/etc/bash.bashrc, ~/.bashrc
System-wide/etc/profile.d/*.sh

Best Practices

โœ… Do This:

export PATH="$HOME/bin:$PATH"                              # โœ… append to PATH
echo 'export MY_VAR="value"' >> ~/.bashrc                  # โœ… persist per-user
printenv PATH                                              # โœ… verify environment
unset TEMP_VAR                                             # โœ… clean up

โŒ Don’t Do This:

var = "value"                                              # โŒ spaces around =
# assume shell variable is inherited                       # โŒ needs export
echo 'export VAR=x' >> /etc/profile                        # โŒ use profile.d instead
# set PATH without including $PATH                         # โŒ breaks command lookup

Common Pitfalls

PitfallWhy It HappensFix
Child process does not see variableNot exportedexport VAR
Variable lost after logoutNot persistedAdd to ~/.bashrc or ~/.profile
var = value failsSpaces around =var=value
PATH broken after editDid not include $PATHexport PATH="$HOME/bin:$PATH"
Variable appears in set but not envIt is a shell variableexport VAR

Real-World Examples

1. Set and export a variable

export APP_ENV="production"

2. View PATH

echo $PATH

3. Add to PATH temporarily

export PATH="$HOME/bin:$PATH"

4. Persist a variable

echo 'export EDITOR=vim' >> ~/.bashrc
source ~/.bashrc

5. System-wide variable

sudo tee /etc/profile.d/app.sh << 'EOF'
export APP_HOME=/opt/app
EOF

6. List environment variables

printenv | less

7. List shell variables

set | grep myvar

8. Unset a variable

unset APP_ENV

9. Check a specific variable

printenv HOME

10. Verify inheritance

export TEST=1; bash -c 'echo $TEST'

Visual

Shell vs Environment Variable

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  PARENT SHELL                                โ”‚
โ”‚  shellvar="local"     โ† shell only           โ”‚
โ”‚  export envvar="global" โ† exported           โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  CHILD PROCESS                               โ”‚
โ”‚  echo $shellvar โ†’ (empty)                    โ”‚
โ”‚  echo $envvar   โ†’ "global"                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Persistence Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ~/.bashrc                                   โ”‚
โ”‚  export MY_VAR="value"                       โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  New interactive shell reads ~/.bashrc       โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  MY_VAR is set and exported                  โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  Available in every new terminal session     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Common Variables

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  PATH   โ†’ where to find commands             โ”‚
โ”‚  HOME   โ†’ user's home directory              โ”‚
โ”‚  USER   โ†’ who you are                        โ”‚
โ”‚  SHELL  โ†’ your shell                         โ”‚
โ”‚  PWD    โ†’ where you are                      โ”‚
โ”‚  TERM   โ†’ your terminal type                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Viewing Commands

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  set     โ†’ everything (shell + env + funcs)  โ”‚
โ”‚  env     โ†’ environment variables only        โ”‚
โ”‚  printenvโ†’ environment variables only        โ”‚
โ”‚  export  โ†’ exported variables                โ”‚
โ”‚  echo $VAR โ†’ one variable's value            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Shell variableLocal to current shell, not inherited
Environment variableExported, inherited by children
Export commandexport VAR=value
View environmentenv, printenv
View all variablesset
Unsetunset VAR
Persist per-user~/.bashrc or ~/.profile
Persist system-wide/etc/profile.d/*.sh
PATHExecutable search path
HOMEHome directory

Key takeaways:

  • export is the dividing line. Without it, a variable is local to the shell. With it, the variable is inherited by child processes .
  • Shell variables and environment variables are different scopes. set shows both; env and printenv show only environment variables .
  • Persistence requires a configuration file. ~/.bashrc for interactive non-login shells, ~/.profile or ~/.bash_profile for login shells .
  • System-wide variables go in /etc/profile.d/. A .sh file there is sourced by /etc/profile for all users .
  • PATH is the most consequential variable. It determines where the shell looks for commands. Always include $PATH when modifying it .
  • unset removes a variable for the current session only. If it is defined in a config file, it returns in the next session .
  • Names are case-sensitive. PATH and path are different variables. By convention, environment variables are uppercase .

Remember: Environment variables are Linux’s mechanism for passing configuration down a process tree. A shell variable is local; an environment variable is exported and inherited. Use export to promote a variable, env or printenv to view the environment, set to see everything, and unset to remove. To persist a variable, write the export line to a shell startup fileโ€”~/.bashrc for interactive shells, ~/.profile for login shells, or /etc/profile.d/ for system-wide settings. The standard variablesโ€”PATH, HOME, USER, SHELL, PWD, TERMโ€”are the ones every script and program expects to find.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!