|

Linux CLI 23 ๐Ÿง printenv and export commands

Environment variables are key-value pairs that the shell and its child processes use to store information โ€” your username, home directory, default editor, and much more. The printenv and export commands let you view and set these variables.


What Are Environment Variables?

Environment variables are dynamic values that affect how processes run.

VariableDescription
HOMEUser’s home directory
USERCurrent username
PATHDirectories the shell searches for commands
PWDPresent working directory
LANGDefault language setting
HOSTNAMEName of the computer
DISPLAYX display (:0 = first display)
SHELLCurrent shell program
EDITORDefault text editor
TERMTerminal type

Key point: Environment variables are inherited by child processes โ€” that’s why they’re called “environment.”


Viewing Variables โ€” printenv

printenv USER
printenv DISPLAY
printenv LANG
printenv PATH
printenv SHELL
printenv PWD
CommandDescription
printenvShow all environment variables
printenv USERShow a specific variable
printenv DISPLAYShow X display
printenv PATHShow command search path

Examples

Show all variables:

$ printenv
SHELL=/bin/bash
USER=kronos
HOME=/home/kronos
PATH=/usr/local/bin:/usr/bin:/bin
PWD=/home/kronos
LANG=en_US.UTF-8
HOSTNAME=olympos
DISPLAY=:0
TERM=xterm-256color
...

Specific variables:

$ printenv USER
kronos

$ printenv HOME
/home/kronos

$ printenv PATH
/usr/local/bin:/usr/bin:/bin

$ printenv SHELL
/bin/bash

$ printenv PWD
/home/kronos

$ printenv DISPLAY
:0

$ printenv LANG
en_US.UTF-8

$ printenv HOSTNAME
olympos

The echo $VAR Alternative

You can also view a variable with echo:

$ echo $USER
kronos

$ echo $HOME
/home/kronos

$ echo $PATH
/usr/local/bin:/usr/bin:/bin

$ echo $USER $HOME
kronos /home/kronos

$ echo "User: $USER, Home: $HOME"
User: kronos, Home: /home/kronos

echo vs printenv:

Aspectecho $VARprintenv VAR
SpeedFasterSlightly slower
FormattingCan mix with textPrints raw value
Exit codeAlways 0Non-zero if not found
Use caseIn scriptsChecking if variable exists

Best practice:

# For display โ€” either works
echo $USER
printenv USER

# For scripting โ€” use printenv to check existence
if printenv MY_VAR > /dev/null; then
    echo "MY_VAR is set"
fi

Common Environment Variables

VariablePurposeExample Value
HOMEHome directory/home/kronos
USERUsernamekronos
PATHCommand search path/usr/bin:/bin
PWDPresent working directory/home/kronos
LANGLanguage/localeen_US.UTF-8
HOSTNAMEMachine nameolympos
DISPLAYX display:0
SHELLCurrent shell/bin/bash
EDITORDefault text editorvim or nano
TERMTerminal typexterm-256color
PS1Shell prompt format\u@\h:\w\$
OLDPWDPrevious directory/var/log
LOGNAMELogin namekronos
UIDUser ID1000

Setting Variables โ€” export

export test="kronos"
echo $test
printenv test
CommandDescription
export VAR=valueSet and export a variable
export VARMark existing variable for export
export -pList all exported variables
export -f funcExport a function
export -n VARRemove export flag

Temporary Variables

Local variable (not exported):

$ test="kronos"
$ echo $test
kronos

$ bash    # Open a new shell
$ echo $test
# (empty โ€” not inherited!)
$ exit

Exported variable (inherited by children):

$ export test="kronos"
$ echo $test
kronos

$ bash    # Open a new shell
$ echo $test
kronos    # โœ… Inherited!
$ exit

Key difference:

TypeCommandInherited by child processes?
Shell variableVAR=valueโŒ No
Environment variableexport VAR=valueโœ… Yes

Verifying Export

$ export test="kronos"
$ echo $test
kronos

$ printenv test
kronos

$ env | grep test
test=kronos

The set Command

Without arguments, set prints all variables โ€” including shell variables and functions:

$ set
BASH=/bin/bash
BASH_VERSION=5.1.16
HOME=/home/kronos
HOSTNAME=olympos
...

With arguments, set is used to configure shell options:

$ set -e           # Exit on error
$ set -x           # Debug mode (print each command)
$ set +x           # Disable debug mode

set vs export:

CommandPurpose
setShow all variables (shell + environment + functions)
exportShow only environment variables
export -pShow only exported variables

Examples:

# All variables
$ set | head -20

# Only environment variables
$ export -p

# Environment variables (alternative)
$ env

Exporting Functions

$ myfunc() {
    echo "Hello from myfunc!"
}

$ export -f myfunc
$ bash
$ myfunc
Hello from myfunc!
$ exit

Use case: Pass helper functions to sub-shells or scripts.


Making Variables Permanent

echo "export VAR_NAME='value'" >> ~/.bashrc
source ~/.bashrc

Step-by-step:

1. Add to ~/.bashrc:

$ echo "export VAR_NAME='value'" >> ~/.bashrc

2. Reload the config:

$ source ~/.bashrc

3. Verify:

$ echo $VAR_NAME
value

Example โ€” Setting a Permanent Variable

# Set EDITOR permanently
$ echo "export EDITOR='nano'" >> ~/.bashrc
$ source ~/.bashrc

$ echo $EDITOR
nano

# Now any program using $EDITOR will use nano
$ crontab -e     # Opens in nano

More examples:

# Add a custom directory to PATH
echo 'export PATH="$PATH:$HOME/bin"' >> ~/.bashrc
source ~/.bashrc

# Set default language
echo "export LANG='en_US.UTF-8'" >> ~/.bashrc

# Set Java home
echo "export JAVA_HOME='/usr/lib/jvm/java-17-openjdk'" >> ~/.bashrc
echo 'export PATH="$JAVA_HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Complete Example Session

# ============================================
# PART 1: VIEWING VARIABLES WITH PRINTENV
# ============================================

$ printenv USER
kronos

$ printenv HOME
/home/kronos

$ printenv PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin

$ printenv SHELL
/bin/bash

$ printenv PWD
/home/kronos

$ printenv LANG
en_US.UTF-8

$ printenv HOSTNAME
olympos

$ printenv DISPLAY
:0

# All variables
$ printenv | head -15
SHELL=/bin/bash
PWD=/home/kronos
LOGNAME=kronos
HOME=/home/kronos
LANG=en_US.UTF-8
...

# ============================================
# PART 2: VIEWING WITH ECHO
# ============================================

$ echo $USER
kronos

$ echo $HOME
/home/kronos

$ echo "User: $USER, Shell: $SHELL"
User: kronos, Shell: /bin/bash

$ echo $PATH
/usr/local/bin:/usr/bin:/bin

# ============================================
# PART 3: SETTING TEMPORARY VARIABLES
# ============================================

# Shell variable (not exported)
$ test="kronos"
$ echo $test
kronos

$ bash
$ echo $test
# (empty โ€” not inherited)
$ exit

# Environment variable (exported)
$ export test="kronos"
$ echo $test
kronos

$ printenv test
kronos

$ bash
$ echo $test
kronos    # โœ… Inherited!
$ exit

# ============================================
# PART 4: LISTING EXPORTED VARIABLES
# ============================================

$ export -p
declare -x HOME="/home/kronos"
declare -x LANG="en_US.UTF-8"
declare -x PATH="/usr/local/bin:/usr/bin:/bin"
declare -x SHELL="/bin/bash"
declare -x USER="kronos"
...

$ env | head -10
SHELL=/bin/bash
PWD=/home/kronos
LOGNAME=kronos
HOME=/home/kronos
...

# ============================================
# PART 5: SET COMMAND
# ============================================

# Show all variables
$ set | head -20
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:...
BASH_VERSION=5.1.16(1)
...

# Enable debug mode
$ set -x
+ echo hello
hello
$ set +x
# Disable debug mode

# ============================================
# PART 6: MAKING VARIABLES PERMANENT
# ============================================

# Add to ~/.bashrc
$ echo "export EDITOR='nano'" >> ~/.bashrc
$ echo "export MY_NAME='kronos'" >> ~/.bashrc

# Reload
$ source ~/.bashrc

# Verify
$ echo $EDITOR
nano
$ echo $MY_NAME
kronos

# ============================================
# PART 7: PRACTICAL EXAMPLES
# ============================================

# Custom command path
$ mkdir -p ~/bin
$ echo 'export PATH="$PATH:$HOME/bin"' >> ~/.bashrc
$ source ~/.bashrc
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/home/kronos/bin

# Set Java environment
$ echo 'export JAVA_HOME="/usr/lib/jvm/java-17-openjdk"' >> ~/.bashrc
$ echo 'export PATH="$JAVA_HOME/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ java -version

# Development environment
$ echo "export NODE_ENV='development'" >> ~/.bashrc
$ echo "export DEBUG=true" >> ~/.bashrc
$ source ~/.bashrc

# ============================================
# PART 8: EXPORT FUNCTIONS
# ============================================

$ greet() {
    echo "Hello, $USER!"
}

$ export -f greet
$ bash
$ greet
Hello, kronos!
$ exit

# ============================================
# PART 9: UNEXPORT AND UNSET
# ============================================

# Remove export flag (keeps variable)
$ export -n test
$ echo $test       # Still works
kronos
$ bash
$ echo $test       # Not inherited
# (empty)
$ exit

# Remove variable entirely
$ unset test
$ echo $test
# (empty)

Quick Reference

Viewing Variables

CommandDescription
printenvShow all environment variables
printenv VARShow specific variable
echo $VARShow variable (quick)
envShow all env variables
setShow all variables + functions
export -pShow only exported variables

Setting Variables

CommandDescription
VAR=valueShell variable (not exported)
export VAR=valueEnvironment variable (exported)
export -f funcExport a function
export -n VARRemove export flag
unset VARRemove variable entirely

Common Variables

VariableMeaning
HOMEHome directory
USERUsername
PATHCommand search path
PWDCurrent directory
SHELLCurrent shell
LANGLanguage setting
HOSTNAMEMachine name
EDITORDefault editor
DISPLAYX display
TERMTerminal type

Best Practices

โœ… Do This:

# Check a variable before using it
if [ -z "$EDITOR" ]; then
    export EDITOR=nano
fi

# Use quotes when displaying variables
echo "$HOME"                    # โœ…
echo "$USER is logged in"

# Add to PATH correctly
export PATH="$PATH:$HOME/bin"   # โœ… Append, don't replace

# Make permanent in ~/.bashrc
echo 'export EDITOR=nano' >> ~/.bashrc
source ~/.bashrc

# Use printenv to check existence
if printenv MY_VAR > /dev/null 2>&1; then
    echo "MY_VAR is set"
fi

# Export only what's needed
export PROJECT_HOME="/home/kronos/projects"

โŒ Don’t Do This:

# Don't forget to export when you need inheritance
test="value"          # โŒ Not inherited by children
export test="value"   # โœ…

# Don't replace PATH โ€” always append
export PATH="/home/kronos/bin"          # โŒ Breaks commands!
export PATH="$PATH:/home/kronos/bin"    # โœ…

# Don't store secrets in ~/.bashrc
export PASSWORD="secret123"   # โŒ Insecure!

# Don't forget to source after editing
nano ~/.bashrc
# ... add export ...
source ~/.bashrc              # โœ… Required

# Don't use single quotes when you need expansion
echo 'User: $USER'            # โŒ Shows $USER literally
echo "User: $USER"            # โœ… Expands

# Don't overwrite important variables
export HOME="/tmp"            # โŒ Breaks everything!

Common Pitfalls

PitfallProblemSolution
Forgot exportVariable not inheritedAdd export
Replaced PATHCommands not foundUse $PATH: prefix
'$VAR' in quotesLiteral $VAR shownUse "$VAR"
Edited .bashrc without sourceChanges not appliedsource ~/.bashrc
Variable lost after rebootNot savedAdd to ~/.bashrc
Spaces around =ErrorVAR=value (no spaces)

Real-World Examples

1. Add Custom Scripts Directory

# Create the directory
$ mkdir -p ~/bin

# Add to PATH permanently
$ echo 'export PATH="$PATH:$HOME/bin"' >> ~/.bashrc
$ source ~/.bashrc

# Now any script in ~/bin can be run from anywhere
$ cp myscript.sh ~/bin/
$ chmod +x ~/bin/myscript.sh
$ myscript.sh    # โœ… Works from anywhere

2. Set Default Editor

# Set nano as default editor
$ echo 'export EDITOR=nano' >> ~/.bashrc
$ source ~/.bashrc

# Now uses nano
$ crontab -e       # Opens in nano
$ git commit       # Uses nano for commit message
$ visudo           # Uses nano

3. Development Environment Variables

# Add to ~/.bashrc
export NODE_ENV=development
export DATABASE_URL="postgres://localhost:5432/myapp"
export API_KEY="dev-key-12345"
export DEBUG=true

source ~/.bashrc

4. Java Development Setup

# Add to ~/.bashrc
export JAVA_HOME="/usr/lib/jvm/java-17-openjdk"
export PATH="$JAVA_HOME/bin:$PATH"
export MAVEN_HOME="/opt/maven"
export PATH="$MAVEN_HOME/bin:$PATH"

source ~/.bashrc
$ java -version
openjdk version "17.0.2"

5. Display Variable in Shell Prompt

# Add to ~/.bashrc
export PS1='[\u@\h \W]\$ '
# Result: [kronos@olympos ~]$

6. Temporary Override for a Command

# Change locale just for one command
$ LANG=es_ES.UTF-8 date
jue 15 ene 2024 10:35:22 UTC

# Back to normal
$ date
Mon Jan 15 10:35:25 UTC 2024

7. Conditional Variable

# In a script
if [ -z "$DEPLOY_ENV" ]; then
    export DEPLOY_ENV="staging"
fi

echo "Deploying to: $DEPLOY_ENV"

8. Show What’s Changed

# Compare current env with defaults
$ printenv | sort > current-env.txt
$ diff /etc/environment current-env.txt

Visual: Variable Inheritance

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           Parent Shell (bash)                โ”‚
โ”‚                                              โ”‚
โ”‚  VAR="value"          โ† Shell variable       โ”‚
โ”‚  export EVAR="value"  โ† Environment variable โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚ forks
                  โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           Child Process (bash)               โ”‚
โ”‚                                              โ”‚
โ”‚  echo $VAR            โ†’ (empty!)             โ”‚
โ”‚  echo $EVAR           โ†’ value โœ…             โ”‚
โ”‚                                              โ”‚
โ”‚  Only EVAR is inherited!                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

CommandPurposeExample
printenvView env variablesprintenv USER
echo $VARQuick viewecho $HOME
export VAR=valueSet env variableexport EDITOR=nano
export -pList exportedexport -p
export -n VARRemove export flagexport -n test
unset VARDelete variableunset test
setShow all variablesset | head
envShow env variablesenv

Key takeaways:

  • Environment variables are key-value pairs inherited by child processes
  • printenv shows all env variables โ€” printenv VAR shows one
  • echo $VAR is a quick way to view โ€” great in scripts
  • Shell variables (VAR=x) are not inherited โ€” environment variables (export VAR=x) are
  • export -p lists only exported variables
  • export -f func exports a function to sub-shells
  • export -n VAR removes the export flag (keeps variable)
  • unset VAR removes the variable entirely
  • Permanent variables go in ~/.bashrc โ€” then source ~/.bashrc
  • Never replace PATH โ€” always append with $PATH:newdir
  • Common variables: HOME, USER, PATH, PWD, SHELL, LANG, EDITOR, DISPLAY

Remember: The key distinction is between shell variables (local to the current shell) and environment variables (inherited by child processes). Use export to make a variable available everywhere. Use printenv to view environment variables and echo $VAR for quick checks. For permanent changes, add to ~/.bashrc and remember to source it. And when modifying PATH, always use $PATH:newdir โ€” never replace the whole thing!


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!