path="$(grep $USER /etc/passwd | cut -d ':' -f 7)"
shell="$(basename -- "$path")"
Then you have to figure out which dot-files this shell would normally read:
man $shell
A shortcut which might work is to list those dot-files which contain the shell name:
ls ~/.*${shell}*
If you want to check if one of the files is actually read during login, you can simply print the file name in each of them, for example:
echo .bashrc
When it comes to declaring the variable «permanently», note that this only extends to the session. There is no way to access the value of a variable without a session, so it has no meaning outside of one. If you mean «read-only», that is shell dependent, and in Bash you can use:
declare -r VAR
if it already has a value, or
declare -r VAR=value
to assign it at the same time. Not all shells have this feature.
name="John Doe"
ip=127.0.0.1
HORRIBLE=1
In Linux (also UNIX) $PATH is environment variable, used to tell the shell where to look for executable files. $PATH variable provides great flexibility and security to the Linux systems and it is definitely safe to say that it is one of the most important environment variables.
Programs/scripts that are located within the $PATH’s directory, can be executed directly in your shell, without specifying the full path to them. In this tutorial you are going to learn how to set $PATH variable globally and locally.
$ echo $PATH
The result should be something like this:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
In different shells this can be:
- Bash shell -> ~/.bash_profile, ~/.bashrc or profile
- Korn Shell -> ~/.kshrc or .profile
- Z shell -> ~/.zshrc or .zprofile
Please note that depending on how you are logging to the system in question, different file might be read. Here is what the bash manual says, keep in mind that the files are similar for other shells:
/bin/bash The bash executable /etc/profile The systemwide initialization file, executed for login shells ~/.bash_profile The personal initialization file, executed for login shells ~/.bashrc The individual per-interactive-shell startup file ~/.bash_logout The individual login shell cleanup file, executed when a login shell exits ~/.inputrc Individual readline initialization file|
$ export PATH=$PATH:/path/to/newdir
Of course in the above example, you should change “/path/to/newdir” with the exact path that you wish to set. Once you have modified your .*rc or .*_profile file you will need to call it again using the “source” command.
For example in bash you can do this:
$ source ~/.bashrc
Below, you can see an example of mine $PATH environment on a local computer:
[email protected][TecMint]:[/home/marin] $ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/marin/bin
If you have any questions or difficulties setting your $PATH environment variable, please do not hesitate to submit your questions in the comment section below.
If you read this far, tweet to the author to show them you care. Tweet a thanks
In Broader terms, an environment variable can be in three types:
- 1. Local Environment Variable
- 2. User Environment Variable
- 3. System wide Environment Variables
- Understanding User-Wide and System-wide Configuration files
- .bashrc
- .bash_profile
- /etc/environment
- /etc/bash.bashrc
- /etc/profile
- Set or Unset Local or Session-wide Environment Variables in Linux
- 1. Using env
- 2. Using unset
- 3. Set the variable name to ”
- Learn How to Create, User-Wide and System-Wide Environment Variables in Linux
- 1. Set and Unset Local Variables in Linux
- 2. Set and Unset User-Wide Environment Variables in Linux
- 3. Set and Unset System-Wide Environment Variables in Linux
- Conclusion
- What Are Environment Variables?
- How to List Environment Variables in Linux
- How to Print Environment Variables in Linux
- How to Make Environment Variables Persistent in Linux
- How to Create a Persistent Global Variable in Linux
- Conclusion
- Scope of environment variables in shells and shell scripts
- Doppler
- Additional resources
- How to set an environment variable to be read-only
- How to execute a command or script in a «clean» environment
- How to check if an environment variable exists
- What are environment variables?
- Environment variable syntax and best practices
- Common environment variables in Linux and Mac
- Using environment variables for application secrets and credentials
- How to execute a script in the context of the current shell
- Using double or single quotes for environment variables
- Setting environment variables for a single command
- How to list environment variables
- How to pass through environment variables when using sudo
- Summary
- How to capture the output of a command and assign it to an environment variable
- Difference between shell and environment variables
- How to delete an environment variable
- How to change and set environment variables
- Where to set environment variables
- How to list all shell and environment variables
1. Local Environment Variable
One defined for the current session. These environment variables last only till the current session, be it remote login session, or local terminal session. These variables are not specified in any configuration files and are created, and removed by using a special set of commands.
2. User Environment Variable
3. System wide Environment Variables
Understanding User-Wide and System-wide Configuration files
.bashrc
.bash_profile
/etc/environment
/etc/bash.bashrc
/etc/profile
$ source <file-name>
Set or Unset Local or Session-wide Environment Variables in Linux
$ var=value OR $ export var=value
1. Using env
$ env –i [Var=Value]… command args…
Here, var=value
corresponds to any local environment variable that you want to use with this command only.
$ env –i bash
Will give bash shell which temporarily would not have any of the environment variable. But, as you exit from the shell, all the variables would be restored.
2. Using unset
Another way to clear local environment variable is by using unset command. To unset any local environment variable temporarily,
$ unset <var-name>
Where, var-name
is the name of local variable which you want to un-set or clear.
3. Set the variable name to ”
Another less common way would be to set the name of the variable which you want to clear, to ''
(Empty). This would clear the value of the local variable for current session for which it is active.
Learn How to Create, User-Wide and System-Wide Environment Variables in Linux
1. Set and Unset Local Variables in Linux
a.) Here, we create a local variable VAR1
and set it to any value. Then, we use unset to remove that local variable, and at the end that variable is removed.
$ VAR1='TecMint is best Site for Linux Articles' $ echo $VAR1 $ unset VAR1 $ echo $VAR1
b.) Another way of creating a local variable is by using export
command. The local variable created will be available for current session. To unset the variable simply set the value of variable to ''
.
$ export VAR='TecMint is best Site for Linux Articles' $ echo $VAR $ VAR= $ echo $VAR
c.) Here, we created a local variable VAR2
and set it to a value. Then in-order to run a command temporarily clearing out all local and other environment variables, we executed 'env –i'
command. This command here executed bash shell by clearing out all other environment variables. After entering 'exit'
on the invoked bash shell, all variables would be restored.
$ VAR2='TecMint is best Site for Linux Articles' $ echo $VAR2 $ env -i bash $ echo $VAR2
2. Set and Unset User-Wide Environment Variables in Linux
$ vi .bashrc
export CD='This is TecMint Home'
$ source .bashrc $ echo $CD
$ vi .bash_profile
export VAR2='This is TecMint Home'
$ source .bash_profile $ echo $VAR2
$ ssh [email protected]
$ echo $VAR2
To remove this variable, just remove the line in .bash_profile
file which you added, and re-source the file.
3. Set and Unset System-Wide Environment Variables in Linux
export VAR='This is system-wide variable'
After that, source the file.
$ source /etc/bash.bashrc
$ echo $VAR $ sudo su $ echo $VAR $ su - $ echo $VAR
export VAR1='This is system-wide variable for only remote sessions'
After adding the variable, just re-source the file. Then the variable would be available.
$ source /etc/profile $ echo $VAR1
To remove this variable, remove the line from /etc/profile
file and re-source it.
export VAR12='I am available everywhere'
After that just source the file and the changes would take effect.
$ source /etc/environment $ echo $VAR12 $ sudo su $ echo $VAR12 $ exit $ ssh localhost $ echo $VAR12
To clear out this variable, just remove the entry in the /etc/environment file and re-source it or login again.
NOTE: Changes take effect when you source the file. But, if not then you might need to log out and log in again.
Conclusion
Thus, these are few ways we can modify the environment variables. If you find any new and interesting tricks for the same do mention in your comments.
In programming, you use variables to store information like strings and numbers temporarily.
Variables can be used repeatedly throughout the code or by your operating system to provide values. You can edit them, overwrite them, and delete them.
In this tutorial, I’ll teach you what environment variables are and how to set them in Linux.
What Are Environment Variables?
Here are some examples of environment variables in Linux:
USER
– This points to the currently logged-in user.HOME
– This shows the home directory of the current user.SHELL
– This stores the path of the current user’s shell, such as bash or zsh.LANG
– This variable points to the current language/locales settings.MAIL
– This shows the location of where the current user’s mail is stored.
How to List Environment Variables in Linux
The command used to display all the environment variables defined for a current session is env
.
Here is the output for my session:
How to Print Environment Variables in Linux
There are two ways to print the already defined environment variables:
printenv VARIABLE_NAME
echo $varname
Let’s print the value of the variable SHELL
using both methods. Here’s an example of printing using printenv
:
export VARIABLE_NAME=value
Let’s define an environment variable, list it, and print its value.
- Define the variable
JAVA_HOME
:
root@Zaira:~# export JAVA_HOME=/usr/bin/java
- Verify by listing it:
- Print its value:
root@Zaira:~# echo $JAVA_HOME
/usr/bin/java
However, the variables defined using this method are stored for the current session only. They won’t be available for the next session.
Let’s verify by opening a new session and printing the variable’s value.
But, we can make the definitions persistent as shown in the next section.
How to Make Environment Variables Persistent in Linux
To make the JAVE_HOME
variable persistent, edit the file .bashrc
and define its value in it.
vi ~/.bashrc
For the changes to take effect, update the .bashrc
file using the source
command:
source .bashrc
Let’s verify by opening a new session.
How to Create a Persistent Global Variable in Linux
For that, we need to first declare a variable and make changes in relevant files where environment variables are read from.
Let’s go step by step.
- I am logged in as the user
Zaira
. I am creating a global variableGLOBAL_VARIABLE
like this:
zaira@Zaira:~$ export GLOBAL_VARIABLE="This is a global variable"
/etc/environment
– This file is used to set up system-wide environment variables.
For the changes to take effect, use the command source /etc/environment
.
/etc/profile
– Variables set in this file are read whenever a bash shell is logged in. Edit this file and use theexport
command:
Time to test!
Conclusion
In this tutorial, you learned how to create and define environment variables in Linux. You also learned how to make them persistent so that you can use them across multiple sessions.
Image by catalyststuff on Freepik.
Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started
Scope of environment variables in shells and shell scripts
Every command, script, and application runs in its own process, each having a unique identifier (typically referred to as PID
). It may run for a few milliseconds (e.g. ls -la
), or many hours, e.g. Visual Studio Code or a Python application server.
To see this in action, let’s run a sleep
command as a background process by appending & after the command so we see its PID in the shell:
# Run a command as a background process using `&` to see the PID of that command
sleep 5 &
When running a command or script from the shell, the current shell is the parent process and the command or script is a child process, which only has access to the environment variables from the current shell or parent process.
For security and isolation, any modifications to environment variables in a child process do not affect the parent process or any other shell sessions.
# Subshell example
(export SUBSHELL_VAR='Test') && echo $SUBSHELL_VAR
# Empty output
# Child shell example by executing string with bash
bash -c "export SUBSHELL_VAR='Test'" && echo $SUBSHELL_VAR
# Empty output
In both instances, the SUBSHELL_VAR
environment variable lived and died within the child process in which it was created and was not visible to the parent process.
Doppler
Real quick shoutout to Doppler. Tired of copying and pasting environment variables into your Vercel, Render, Heroku, etc and manually sharing your .env file with teammates, give Doppler a try to automate the pain away. Now back to the post!
Additional resources
There’s obviously a lot more to shell programming than just environment variables and here are three essential resources to take your shell usage and scripts to the next level:
- Bite Size Bash by Julia Evans (not free but totally worth it)
- Shellcheck static analysis tool
- Google shell style guide
How to set an environment variable to be read-only
To make an environment variable (or function) read-only, just use the readonly command:
readonly export READONLY_VAR=1
READONLY_VAR=2
# >> READONLY_VAR: readonly variable
How to execute a command or script in a «clean» environment
Sometimes, you’ll want to execute a command or script in a «clean» environment, devoid of all environment variables using env -i
:
env -i printenv
# Empty output as no env vars exist
How to check if an environment variable exists
At some point, you’ll need to conditionally check for the existence of an environment variable.
# deathstar-attack.sh
if [ -z "$DEATHSTAR_SHIELD_DOWN" ]; then
echo "Break off the attack! The shield is still up!"
else
echo "The shield is down! Commence attack on the Death Star's main reactor!"
fi
Then let’s execute the script without defining the DEATHSTAR_SHIELD_DOWN
variable:
bash deathstar-attack.sh
# >> Break off the attack! The shield is still up!
Now with defining DEATHSTAR_SHIELD_DOWN
:
export DEATHSTAR_SHIELD_DOWN="Yes"
bash deathstar-attack.sh
# >> The shield is down! Commence attack on the Death Star's main reactor!
# deathstar-attack-2.sh
if [ -z "${DEATHSTAR_SHIELD_DOWN+x}" ]; then
echo "Break off the attack! The shield is still up!"
else
echo "The shield is down! Commence attack on the Death Star's main reactor!"
fi
unset DEATHSTAR_SHIELD_DOWN
bash deathstar-attack-2.sh
# >> Break off the attack! The shield is still up!
export DEATHSTAR_SHIELD_DOWN=""
bash deathstar-attack-2.sh
# >> The shield is down! Commence attack on the Death Star's main reactor!
What are environment variables?
# Setting an environment variable
# The `export` keywords essentially means "make this globally accessible"
# No spaces on either side of the equals sign.
# Quotes recommended
export FULL_NAME="Darth Vader"
# Getting an environment variable's value
# Note the $ prefix used for referencing
echo "Anakin Skywalker is now $FULL_NAME"
# >> Anakin Skywalker is now Darth Vader
That’s only the tip of the iceberg, so let’s dive deeper.
Environment variable syntax and best practices
Here are some rules and best practices for assigning and using environment variables:
- Variable names may only contain characters (a-z,A-Z), numbers, and underscores
- No spaces on either side of the equals sign
- The naming convention is
CAPITALIZED_SNAKE_CASE
- Always surround values with quotes, e.g.
export KEY="value"
- Always surround variables usage with quotes, e.g.
echo "$KEY"
- Only export a variable if it will be used by script called from that shell or child process
- Avoid exporting variables that contain sensitive information such as API tokens by setting them for a single command only.
Common environment variables in Linux and Mac
$PATH
: A colon-separated list of directories for looking up binaries and scripts that don’t need the full path in order to execute them, e.g.echo
instead of/bin/echo
as/bin
is in$PATH
$HOME
: The user’s home directory for the current shell$PWD
: The directory location in the current shell$SHELL
: The executable for the current shell, e.g./bin/bash
$HOSTNAME
: The hostname of the current machine as it may appear in your local network
Using environment variables for application secrets and credentials
Environment variables are arguably the best way to supply config and secrets to deployed applications such as a Python or Node.js app.
This is because Virtual Machines (VM) and Docker containers provide a sandboxed environment for applications to execute in, therefore any environment variable only affects that specific application in that VM or container.
Because applications are configured differently from development to production, configuring an app using environment variables means only the values need to change when deploying to different environments, not the source code.
Environment variables should also be used to configure CI/CD jobs and environments, e.g, GitHub Actions.
Supplying application config and secrets using environment variables is precisely what the Doppler CLI does, and our mission is to make this as fast, easy, and secure as possible with integrations for every major every cloud provider and platform.
How to execute a script in the context of the current shell
Most times, you’ll want a script executed in a child process that can access, but can’t modify the current shell. But there are scenarios where you’ll want to load functions or variables from a script into the current shell.
An example is the bash autocompletion code from homebrew on macOS using the leading period syntax:
# Load bash autocompletion code into the current shell
. /usr/local/Cellar/bash-completion/1.3_3/etc/bash_completion
Let’s demonstrate this functionality by loading variables into the current shell using the below script, saving it as current-shell-vars.sh:
#!/usr/bin/env bash
COOL_DROID="R2-D2"
ANNOYING_DROID="C-3PO"
Then make the script executable:
chmod +x current-shell-vars.sh
Simply executing the script will only make the variables available to the code inside the script:
./current-shell-vars.sh
echo $COOL_DROID
# empty output
To execute it in the current shell, we prefix the command with a leading period:
. ./current-shell-vars.sh
echo "$COOL_DROID is cool but $ANNOYING_DROID is pretty annoying"
# >> R2-D2 is cool but C-3PO is pretty annoying
Be very careful with this functionality and only execute scripts you absolutely trust!
If you’re wondering, «doesn’t source
do the same thing?», yes it does, but it’s only available in bash, so the above form is simply more portable
Using double or single quotes for environment variables
Using double or single quotes depends on your requirements and as a rule, always quote your values to avoid unintended word-splitting issues:
export FULL_NAME=Obi-Wan Kenobi
# >> bash: Kenobi: command not found
FULL_NAME="Obi-Wan Kenobi"
echo "Help me $FULL_NAME. You're my only hope."
# >> Help me Obi-Wan Kenobi... You're my only hope
echo "My username is $(whoami) and I am currently in the $PWD directory"
# >> My username is ryan and I am currently in the /home/ryan/dev directory
If using double quotes for variable referencing but also want to output the $ sign, then you need to escape it using the backslash \ character:
export TRAVELLERS="Luke and Obi-Wan"
echo "Congratulations $TRAVELLERS, you've just won passage on the Millenium Falcon worth \$17,000"
# >> Congratulations Luke and Obi-Wan, you've just won passage on the Millenium Falcon worth $17,000
Another option instead of escaping a reserved symbol such as $ is using single quotes, as it prevents variable referencing and command substitution because the string is not interpolated:
echo 'The $PWD env var is the path to the current working directory'
# >> The $PWD env var is the path to the current working directory
export FOO="foo"
echo "$FOObar" # Output will be empty as variable `$FOObar` does not exist
echo "${FOO}bar"
# >> foobar
Setting environment variables for a single command
Sometimes, you’ll want to expose or change environment variables only for the life of a single command, script, or child process.
# baby-yoda.sh
echo "Baby Yoda is named $BABY_YODA"
First, let’s look at how to do this the long and inefficient way:
export BABY_YODA="Grogu"
bash baby-yoda.sh
# >> Baby Yoda is named Grogu
unset BABY_YODA
We can instead turn this into a single command by defining the variable before command:
BABY_YODA="Grogu" bash baby-yoda.sh
# >> Baby Yoda is named Grogu
Now you might be wondering what if you want to temporarily expose an environment variable to multiple commands? It may not work the way you would expect. Let’s try running our script twice using &&
syntax:
BABY_YODA="Grogu" bash baby-yoda.sh && bash baby-yoda.sh
# >> Baby Yoda is named Grogu
# >> Baby Yoda is named
The second script invocation did not have the BABY_YODA
environment variable set because the shell interpreted the above command as:
BABY_YODA="Grogu" bash baby-yoda.sh
bash baby-yoda.sh
To temporarily expose an environment variable to multiple commands, we can pass a string to bash to execute:
BABY_YODA="Grogu" bash -c 'bash baby-yoda.sh && bash baby-yoda.sh'
# >> Baby Yoda is named Grogu
# >> Baby Yoda is named Grogu
How to list environment variables
The printenv
command does exactly as it describes, printing out all environment variables available to the current shell.
You can combine printenv
with grep
to filter the list environment variables:
To output the value of a specific environment variable, you should use also printenv
:
If you’re wondering how to tell if printenv SOME_VAR
actually worked or whether SOME_VAR
was just empty, you can inspect the $?
variable after the printenv
command and if the exit code was 0, the environment variable exists.
How to pass through environment variables when using sudo
By default for security, commands run as root using sudo
do not pass through environment variables from the current shell, but you can override this using the --preserve-env
flag:
# Print the environment variables for the root user
sudo printenv
# Pass through the environment variables from the current shell
sudo --preserve-env printenv
Use this caution!
Summary
Awesome work! You now know a ton of great and practical stuff about environment variables for Linux and Mac and we hope you enjoyed the journey!
If you want thinking about environment variables to be a thing of the past, go on easy mode with Doppler.
How to capture the output of a command and assign it to an environment variable
TODAYS_DATE=$(date +"%B %-d, %Y")
echo "Today's date is $TODAYS_DATE"
Difference between shell and environment variables
Simplistically, shell variables are local in scope whereas environment variables are global, but let’s explore this further with examples.
Shell variables should be used when they are only needed in the current shell or script in which they were defined.
# Shell variable as it does not use the `export` command
WOOKIE="Chewbacca"
echo "The Wookie's name is $WOOKIE"
# >> The Wookie's name is Chewbacca
# In a new shell
echo "The Wookie's name is $WOOKIE"
# >> The Wookie's name is
# shell-var-test.sh
echo "The Wookie's name is $WOOKIE"
And shell-var-test.sh
was run even after NAME
was defined, it’s not accessible to the script.
WOOKIE="Chewbacca"
bash shell-var-test.sh
# >> The Wookie's name is
Environment variables, on the other hand, are designed to be accessible to scripts or child processes and differ from shell variables by use of the export command.
export WOOKIE="Chewbacca"
bash shell-var-test.sh
# >> The Wookie's name is Chewbacca
It’s also true that any variable changes inside a script or new process do not affect the shell where they were executed from, even for environment variables.
We delve deeper into the scope of environment variables in shells and shell scripts later in this article, as well as how to change the default scoping behavior by learning how to execute a script in the context of the current shell.
How to delete an environment variable
The unset
command is used to remove a variable:
export FAV_DROID="R2-D2"
echo "My favorite droid is $FAV_DROID"
# >> My favorite droid is R2-D2
unset FAV_DROID
echo "My favorite droid is $FAV_DROID"
# >> My favorite droid is
The deletion of an environment variable only affects the current shell.
How to change and set environment variables
Changing an environment variable is no different from changing a shell variable:
export FAV_JEDI="Obi-Wan Kenobi"
echo "My favorite Jedi is $FAV_JEDI"
# >> My fav jedi is Obi-Wan Kenobi
FAV_JEDI="Rey Skywalker"
echo "My favorite Jedi is now $FAV_JEDI"
# >> My favorite Jedi is now Rey Skywalker
You can also modify a variable using its original value to create a new value. You’ve most likely seen this used before in a ~/.bash_profile
or ~/.bashrc
file when appending a directory to the $PATH
variable:
# Add the `~/bin` directory to $PATH for user scripts and self-compiled binaries
PATH=$PATH:~/bin
Note that we did not put export
before PATH
in this example, and that’s because PATH
was already exported, so putting export
again does nothing.
Where to set environment variables
To avoid simply repeating content for the sake of it, check out this excellent comprehensive article from Unix/Linux Stack Exchange question: How to permanently set environmental variables.
How to list all shell and environment variables
It’s possible to list both shell and environment variables using the set command:
( set -o posix ; set ) | less
You’ll notice that you see not just variables, but functions too.
If using bash, you can use compgen
which is less noisy: