LearnAI ToolsCareerPractice BuildsPlayDevelopmentContact
Lesson 1113 min read

Environment Variables, PATH and .bashrc

Use shell and environment variables, understand how PATH finds commands, add your own commands, and customise the shell with aliases in .bashrc.

On this page 10 sections

Introduction

Every program on Linux starts with a set of named values called environment variables: who you are, where your home folder is, which folders contain commands. Applications use them for configuration too — API keys, database addresses, whether to run in development or production mode. Understanding them explains countless “command not found” errors and is essential for deploying software.

What You Will Learn
  • How to read and set variables.
  • Why export matters for programs you run.
  • How the PATH variable decides which commands exist.
  • How to make settings and aliases permanent in ~/.bashrc.

Reading Variables

A $ in front of a name gives its value. By convention, environment variables are written in capitals:

echo "Home: $HOME"
echo "User: $USER"
echo "Shell: $SHELL"
Output

Click Run to see what this code prints.

printenv prints variables by name, and on its own lists all of them (env does the same):

printenv HOME USER SHELL
Output

Click Run to see what this code prints.

Shell vs Environment Variables

Create a variable by writing NAME=value — with no spaces around the =. A plain variable only exists in the current shell; programs you start from it cannot see it:

GREETING="Hello"
echo "$GREETING from the shell"
bash -c 'echo "child process sees: [$GREETING]"'
Output

Click Run to see what this code prints.

(bash -c starts a new program — a child process — that runs one command.) export turns it into an environment variable, which is copied to every program started from this shell:

export GREETING="Hello"
bash -c 'echo "child process sees: [$GREETING]"'
Output

Click Run to see what this code prints.

You can also set a variable for a single command by writing it in front. This is how apps are often started in a particular mode:

APP_ENV=production bash -c 'echo "APP_ENV is $APP_ENV"'
echo "after: [$APP_ENV]"
Output

Click Run to see what this code prints.

Mini Challenge · Spot the Problem

Priya types API_URL=https://api.example.com and then runs node app.js, but the app says API_URL is not set. What is missing?

Choose one answer

How PATH Finds Commands

When you type ls, how does the shell know where the program is? It looks in each folder listed in the PATH variable, in order, separated by colons:

echo $PATH
Output

Click Run to see what this code prints.

echo $PATH | tr ':' '\n'
Output

Click Run to see what this code prints.

The first folder that contains a matching program wins. If none of them does, you get “command not found” — even if the program exists somewhere else on the disk.

Adding Your Own Commands

Priya writes a small script called greet in a folder ~/bin and makes it executable with chmod +x ~/bin/greet:

~/bin/greet
#!/bin/bash
echo "Hi, $USER! Today is $(date +%A)."

With a PATH that does not include that folder, the shell cannot find it:

greet
Output

Click Run to see what this code prints.

Add the folder to the front of PATH, and greet becomes a command like any other:

export PATH="$HOME/bin:$PATH"
greet
which greet
Output

Click Run to see what this code prints.

Always Include the Old PATH

Write PATH="$HOME/bin:$PATH", never PATH="$HOME/bin". Leaving out :$PATH replaces the whole list, and suddenly ls, cd’s friends and every other command become “not found” in that terminal.

Making It Permanent: .bashrc

Variables set in a terminal disappear when you close it. To apply settings to every new terminal, add them to ~/.bashrc, a script Bash runs each time it starts an interactive shell. Ubuntu’s default file already defines some aliases — shortcuts for longer commands:

grep -n "^alias l" ~/.bashrc
Output

Click Run to see what this code prints.

So ll is really ls -alF. Priya appends her own settings to the end of the file (with nano, or with a here-document as shown in lesson 5):

tail -n 5 ~/.bashrc
Output

Click Run to see what this code prints.

Changes apply to new terminals. To load them into the current one, run source ~/.bashrc. In a new shell, everything is in place:

type update
echo EDITOR=$EDITOR
greet
Output

Click Run to see what this code prints.

Mini Challenge · Put It in Order

Put the steps for permanently adding ~/tools to your PATH in order.

  1. Open ~/.bashrc in an editor
  2. Run source ~/.bashrc (or open a new terminal)
  3. Add the line export PATH="$HOME/tools:$PATH" at the end
  4. Save the file
  5. Check with echo $PATH

Common Mistakes

Avoid These Mistakes
  • Putting spaces around = (NAME = value is a command called NAME, not an assignment).
  • Forgetting export, so programs never see the variable.
  • Overwriting PATH instead of adding to it.
  • Committing secrets like API keys into .bashrc in a shared dotfiles repository.

Frequently Asked Questions

.profile runs once when you log in, .bashrc runs for every interactive Bash shell. On Ubuntu, .profile also loads .bashrc, so for most personal settings .bashrc is the right place.

Every language has a way: process.env.API_URL in Node.js, os.environ["API_URL"] in Python. That is how deployed apps receive settings like database URLs without hard-coding them.

A file of NAME=value lines that many frameworks load into environment variables at start-up. It often contains secrets, so it belongs in .gitignore.

Key Takeaways

  • $NAME reads a variable; NAME=value sets one (no spaces around =).
  • export makes a variable visible to programs you start.
  • PATH is the list of folders searched for commands, in order.
  • Add folders with PATH="$HOME/bin:$PATH" — never drop the old value.
  • Put permanent settings and aliases in ~/.bashrc, then source it.

Summary

You now understand how the shell is configured and how programs receive settings. Next you will combine everything so far into shell scripts: files of commands that automate real work.

Next Lesson →

Shell Scripting: Automate Your Work with Bash