Linux how to set env variable: export VAR=value for current session, add to ~/.bashrc or ~/.zshrc for user-persistent, /etc/environment for system-wide. The team that uses export for testing, ~/.bashrc for personal config, and /etc/environment for shared defaults has the right placement for each scope.
Table of contents
- Temporary (current session)
- User-persistent (~/.bashrc)
- System-wide (/etc/environment)
- /etc/profile.d/ for shell-aware config
- .env files in projects
- Persistent for systemd services
- Persistent in cron
- Inspect env vars
- FAQ
Temporary (current session)
export MY_VAR="hello"
# In a subshell:
MY_VAR="hello" python script.py
The team that uses export for testing has a session-only variable. Lost on logout.
User-persistent (~/.bashrc)
# Append to ~/.bashrc
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
# Apply
source ~/.bashrc
The team that puts personal config in ~/.bashrc has persistent env vars per user. Survives logout.
System-wide (/etc/environment)
Edit /etc/environment (no shell syntax, just KEY=VALUE):
JAVA_HOME=/usr/lib/jvm/java-11
DOCKER_HOST=unix:///var/run/docker.sock
Login shells source this. The team that uses /etc/environment has system-wide defaults available to all users.
/etc/profile.d/ for shell-aware config
# /etc/profile.d/myapp.sh
export MYAPP_HOME=/opt/myapp
export PATH="$PATH:$MYAPP_HOME/bin"
The team that uses /etc/profile.d/ for shell-aware system-wide config (vs /etc/environment which is parsed as KEY=VALUE only).
.env files in projects
For project-specific:
# .env (gitignored)
DATABASE_URL=postgresql://localhost/mydb
SECRET_KEY=dev-only
Loaded by tools like docker-compose, dotenv, etc. The team that uses .env files has per-project config without polluting the shell.
Persistent for systemd services
For systemd unit, set env vars in the unit file or via EnvironmentFile:
# /etc/systemd/system/myapp.service
[Service]
Environment=KEY=value
EnvironmentFile=/etc/myapp/env
The team that uses EnvironmentFile for services has per-service config.
Persistent in cron
Cron has minimal env. Set in crontab or wrapper script:
PATH=/usr/local/bin:/usr/bin:/bin
0 * * * * /opt/myapp/run.sh
The team that uses cron-aware env has working scheduled jobs.
Inspect env vars
# Current shell
env | grep MY_VAR
# All vars (sorted)
env | sort | less
# Specific var
echo "$MY_VAR"
The team that uses env has visibility.
FAQ
What’s the difference between .bashrc and .bash_profile?
.bash_profile: login shells. .bashrc: interactive non-login shells. The team that puts env vars in .bashrc has them in most interactive sessions.
Why doesn’t my export persist across sessions?
Because it’s only in the current shell process. The team that adds to ~/.bashrc has persistence.
Can I set env vars in /etc/profile?
Yes - applies to all login shells. The team that uses /etc/profile for system-wide shell-aware config.
What’s the precedence?
Login shell: /etc/profile -> /etc/profile.d/* -> ~/.bash_profile. Interactive: /etc/bash.bashrc -> ~/.bashrc. The team that has the right ordering has predictable behavior.
Should I use /etc/environment or /etc/profile.d/?
/etc/environment: KEY=VALUE format, no shell syntax. /etc/profile.d/: full shell script. The team that picks based on needs has the right choice.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: