Here’s a FAANG-level interview guide on Linux environment variables, including variable types, system-wide vs user-specific variables, real-world examples, and common interview questions with detailed explanations.
🔧 1. What are Environment Variables in Linux?
Environment variables are key-value pairs used to configure the behavior of the system or programs. They are used for:
Setting system-wide configurations
Telling applications where to find binaries or libraries
Managing user preferences
🧠Think of them as "global variables" available to processes.
🧱 2. Types of Variables in Linux
🖥️ 3. System-wide vs User-specific Variables
🔒 System-wide Variables
Apply to all users
Defined in files:
/etc/environment – Persistent, general purpose
/etc/profile – For login shells
/etc/bash.bashrc – For interactive non-login shells (Ubuntu)
/etc/profile.d/*.sh – For modular configurations
✅ Example:
# /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64"
👤 User-specific Variables
Defined per user
Set in files like:
~/.bashrc – For interactive shell sessions
~/.bash_profile or ~/.profile – For login shells
✅ Example:
🧪 4. How Variables Are Used (with Examples)
Setting and exporting:
MY_VAR="hello" # Shell variable
export MY_VAR # Becomes environment variable
Making persistent:
echo 'export MY_VAR="hello"' >> ~/.bashrc
source ~/.bashrc
Reading:
echo $MY_VAR
Unsetting:
unset MY_VAR
🧠5. Interview-Level Deep Dive & Real-World Examples
Scenario: Application not picking up JAVA_HOME?
Diagnosis:
Check /etc/environment, /etc/profile, ~/.bashrc
Check if export JAVA_HOME is present
Use env | grep JAVA_HOME or printenv JAVA_HOME
Scenario: User's PATH missing /usr/local/bin
Fix:
echo 'export PATH=$PATH:/usr/local/bin' >> ~/.bashrc
source ~/.bashrc
Scenario: Setting custom environment for a systemd service
❓ 6. FAANG-Level Interview Questions (with Answers)
✅ Q1: What's the difference between export and just assigning a variable?
A: Assigning like VAR=value makes it a shell variable. export VAR=value makes it available to child processes.
✅ Q2: How would you debug a missing PATH entry for a CLI tool?
A:
Run echo $PATH
Check user dotfiles: ~/.bashrc, ~/.profile
Run which <tool>
Add missing path: export PATH=$PATH:/path/to/tool
✅ Q3: How are environment variables inherited in Linux?
A: A child process inherits the environment variables of its parent shell. But it won’t inherit shell variables unless exported.
✅ Q4: How do you set a system-wide environment variable that persists after reboot?
A: Edit /etc/environment and reboot or re-login. Example:
echo 'FOO=bar' | sudo tee -a /etc/environment
✅ Q5: What’s the difference between ~/.bashrc, ~/.bash_profile, and /etc/profile?
✅ Q6: How can you pass environment variables to a process launched via cron?
A:
Set them in the crontab:
OR source .bashrc inside the script
🧰 7. Commands You Should Know
📄 8. Cheatsheet Summary
📘 Suggested Deep Reading / Practice
man bash – Read ENVIRONMENT section
Practice customizing dotfiles (.bashrc, .profile) on a VM
High-Level Differences
1. ~/.bashrc
Use Case:
Used for interactive shell settings like aliases, prompt, functions.
When it runs:
Terminal opened in GUI (non-login shell)
Sourced from .bash_profile for login shells
2. ~/.bash_profile
Use Case:
Used to configure environment for login shells.
Login shell means when you SSH or log in via a TTY.
Important:
On most Linux distributions, interactive login shell reads .bash_profile only once at login.
3. /etc/profile
Use Case:
Global initialization script for all users on login shells.
Used for system-wide behavior like resource limits, common paths.
4. /etc/environment
Use Case:
Pure key-value pair environment variables for all users, non-shell-specific.
Parsed by PAM during login
Used by GUI apps and non-shell login systems like GDM
When Each File Is Used (Scenario Table)
Real-World Example (CI/CD DevOps)
Goal: Ensure Jenkins user uses a specific Java version
You'd use:
/etc/environment: Set global JAVA_HOME
~/.bash_profile of jenkins: Load custom env and source ~/.bashrc
~/.bashrc: Add aliases, path updates for command-line tools
FAANG-Level Interview Q&A
Q1: What’s the difference between ~/.bashrc and ~/.bash_profile? When is each executed?
Answer:
~/.bash_profile is for login shells
~/.bashrc is for interactive non-login shells
Typically, .bash_profile sources .bashrc to ensure a consistent environment
Explanation: On most Linux systems, GUI terminals don’t count as login shells, so .bashrc is used directly. If you SSH, .bash_profile is triggered.
Q2: A developer sets an alias in ~/.bashrc but it doesn’t work over SSH. Why?
Answer:
Because ~/.bashrc is not executed in a login shell (SSH is a login shell). They should place:
...in their ~/.bash_profile.
Explanation: Sourcing .bashrc from .bash_profile ensures both login and non-login shells behave similarly.
Q3: Why use /etc/environment instead of /etc/profile?
Answer:
/etc/environment is shell-agnostic and gets loaded by PAM (login manager)
GUI apps or cron jobs that don’t invoke login shells will still get vars from /etc/environment
Explanation: For system-wide GUI variable settings (like JAVA_HOME for IntelliJ or VSCode), use /etc/environment.
Q4: A script runs via cron, but it fails due to missing environment variables. What’s the fix?
Answer:
Cron jobs don’t source any shell files like .bashrc or .bash_profile
Use /etc/environment or export variables directly in the crontab like:
* * * * * JAVA_HOME=/usr/lib/jvm/java-11-openjdk /path/to/script.sh
Explanation: Cron uses minimal environment, so explicit exports or /etc/environment are needed.