If you’ve ever SSH’d into a server, changed some setting, and then… nothing happened, there’s a good chance environment variables were involved.
Before: your script can’t find programs, your app can’t see its config, and every new shell feels like it “forgets” what you just set.
After: you know exactly how to view, set, export, and persist environment variables so your shell and apps behave the way you expect.
This guide is for anyone working on Linux servers or local dev boxes using Bash. We’ll stay practical and stick to what you actually need: reading variables, changing them, and making them stick.
What Are Environment and Shell Variables (In Plain Language)
When you open a terminal or SSH into a server, your shell (usually Bash) builds a little world of settings. That world is called the environment.
Inside that environment, you have variables like:
– Paths to programs
– Language settings
– Home directory
– Session-specific flags
These are stored as strings in KEY=VALUE form. If a variable holds multiple values (like PATH), they’re usually separated by colons :.
There are two main types you’ll deal with:
- Shell variables – Live only in your current shell session. Bash knows them, but child processes do not.
- Environment variables – Passed from the shell to child processes (like scripts or programs you run).
You control these using Bash built-ins and commands like:
– printenv or env → to view environment variables
– set → to see all shell + environment variables
– export → to turn a shell variable into an environment variable
Every time you start a shell session, Bash pulls settings from various config files (like ~/.bashrc or ~/.profile) to build that environment.
Step 1: Safely Inspect Your Environment
Before changing anything, it’s good to just look around.
View environment variables with `printenv`
printenv shows you environment variables only.
printenv
That will dump all environment variables to your screen.
If you want a single variable, pass its name:
printenv PATH
printenv HOME
printenv SHELL
This is useful to check what your server thinks your settings are before debugging a script.
View environment variables with `env`
env is similar. Run it with no arguments to see the environment:
env
In day-to-day troubleshooting, printenv and env are both useful to confirm what’s actually being passed to programs.
View *all* variables with `set`
If you want to see everything your shell knows about (shell variables + environment variables + functions), use:
set
This can be a long list, so it’s common to combine with less:
set | less
Use this when you suspect something is defined as a shell variable but not exported to the environment.
Step 2: Create and Read Shell Variables
Now let’s set some variables in the current shell.
Set a shell variable
Shell variables are simple key-value strings:
MY_NAME="SepedaTua"
PROJECT_ROOT="/var/www/myproject"
No spaces around =. If the value has spaces, wrap it in quotes.
At this point, MY_NAME is known only to your current shell, not to programs you run from it.
Read a shell or environment variable
Use echo with the $ prefix:
echo "$MY_NAME"
echo "$PROJECT_ROOT"
If you see nothing, the variable is empty or not defined.
You can also ask printenv for it, but remember printenv only knows about environment variables. So if printenv MY_NAME returns nothing, that just means it hasn’t been exported yet.
Step 3: Export Variables to the Environment
By default, a plain shell variable is not visible to child processes.
If you run a script or command that needs to read a variable, you must export it so it becomes an environment variable.
Convert a shell variable into an environment variable
You can do it in two steps:
MY_NAME="SepedaTua"
export MY_NAME
Or in one shot:
export MY_NAME="SepedaTua"
Now check it with:
printenv MY_NAME
Why export matters
Let’s say you have a script show-name.sh:
#!/usr/bin/env bash
echo "Name is: $MY_NAME"
If you just do:
MY_NAME="SepedaTua"
./show-name.sh
The script will most likely print:
Name is:
Because MY_NAME is only a shell variable.
But if you export it:
export MY_NAME="SepedaTua"
./show-name.sh
Now the child process (the script) can see MY_NAME through the environment.
That’s the main point of export: make the variable available to anything your shell starts.
Step 4: Temporary vs Persistent Variables
So far, everything we set lives only until you close the terminal. When the shell process ends, the environment vanishes.
To make variables survive new sessions, you use shell configuration files. Common ones are:
~/.bashrc~/.profile
Each time a Bash session starts, it reads from these (depending on whether it’s a login shell or interactive shell) and builds the environment.
Safe habit before editing
Before changing any config file, make a quick backup:
cp ~/.bashrc ~/.bashrc.backup
cp ~/.profile ~/.profile.backup
If you mess something up, you can restore it:
cp ~/.bashrc.backup ~/.bashrc
# then start a new shell
It’s a tiny step that can save you from weird login problems.
Add persistent variables to `~/.bashrc` or `~/.profile`
If you want a variable to be set each time you open a terminal, add it to one of these files.
For example, open ~/.bashrc in your editor:
nano ~/.bashrc
Add lines like this at the bottom:
MY_NAME="SepedaTua"
export MY_NAME
Or combine them:
export MY_NAME="SepedaTua"
Save and close.
Now reload the file in your current shell:
source ~/.bashrc
Then verify:
printenv MY_NAME
You should see your value. New shells will also get it automatically.
Which file to use?
Both ~/.bashrc and ~/.profile are commonly used for user-specific settings.
~/.bashrcis often used for interactive shell settings (aliases, prompts, variables for terminals).~/.profileis often used for login session settings.
The exact behavior can vary a bit depending on your system, but for most day-to-day shell work, adding exports to ~/.bashrc is enough.
Step 5: Quick Checks and Common Gotchas
Here are a few common issues you’ll probably run into at some point.
“I set a variable but my script can’t see it”
Check if it’s really exported:
export MY_VAR="something"
printenv MY_VAR
If printenv shows nothing, it’s not in the environment. You might have:
MY_VAR = "something" # wrong
No spaces are allowed around =. Correct it to:
MY_VAR="something"
export MY_VAR
“The variable works in this terminal but not when I reconnect”
You probably only set it in the live shell, not in a config file.
Add it to ~/.bashrc or ~/.profile as described earlier, then either:
source ~/.bashrc
or just open a new terminal/SSH session and test again.
“How do I see if a variable is shell-only or environment?”
Use both set and printenv.
set→ shows shell + environment variablesprintenv→ shows only environment variables
If a variable shows up in set but not in printenv, it’s likely just a shell variable and not exported.
Example flow:
MY_TEMP="test"
set | grep MY_TEMP # should show
printenv MY_TEMP # probably empty
export MY_TEMP
printenv MY_TEMP # now shows
Step 6: Practical Use Cases for Everyday Admin Work
Let’s tie it together with some realistic server scenarios.
1. Adjusting search paths (like PATH)
Your shell uses variables like PATH to know where to look for programs.
To view it:
printenv PATH
If you temporarily want to prepend a directory (for this session only):
PATH="/opt/mytools/bin:$PATH"
export PATH
That tells the shell to look in /opt/mytools/bin first when you run commands.
2. Setting config locations for tools
Some tools read their configuration from environment variables (for example, a CONFIG_FILE variable).
In your current session:
export CONFIG_FILE="/etc/myapp/config.yml"
Add that exact line in ~/.bashrc if you want it persistent.
3. Checking what a script actually inherits
If a script behaves differently when run from cron vs your shell, environment differences might be the cause.
From your shell, run:
env > /tmp/env-from-shell.txt
Then in cron (or another context), have a job that does:
env > /tmp/env-from-cron.txt
Compare the two files to see what variables are missing or different. The same env and printenv mechanics apply in both cases.
Recap and Next Step
You now know how to:
– Inspect your environment with printenv, env, and set
– Create shell variables in your current session
– Export variables so child processes can see them
– Persist variables across sessions using ~/.bashrc or ~/.profile
With these basics, a lot of “why doesn’t this script see my setting?” headaches go away.
If this saved you time, bookmark CrushEdge for more fixes.
No Comments