Recommended Free Tools
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To make an environment variable reach a program, set it at the scope that launches that program. A value exported in one terminal does not change a service that was started by systemd, and a value added to a shell startup file does not reach a process that never runs through that shell.
What an environment variable is
An environment is a set of name=value strings that the operating system hands to a process when it starts. A child process receives the environment its parent passes to it, and it cannot reach back into the parent to change that environment. This is why the same variable can behave differently in two terminals, a desktop launcher, and a background service.
In Bash and other Bourne-style shells, a shell variable and an environment variable are not the same thing. A plain assignment such as APP_MODE=development creates a shell parameter. Only variables marked with the export attribute are copied into the environment of commands the shell starts.
Set a variable for one command
To give a program a value for a single run, put the assignment directly before the command:
#1 Best Overall
APP_MODE='test' ./run-tests
The GNU Bash Reference Manual describes this form directly: when parameter assignments appear before a simple command, they are part of that command’s environment for as long as it runs. The shell that launched the command keeps its own value, if it has one, so nothing else changes.
Set a variable for the current shell
To make a value available to the current shell and to every command it starts afterward, export it:
export APP_MODE='development'
printenv APP_MODE
export -p
The POSIX specification for export says the shell gives the export attribute to the named variables so that they are in the environment of subsequently executed commands. printenv APP_MODE confirms the value an external program sees, and export -p lists every exported name in Bash. To remove the variable from the current shell, run unset APP_MODE.
Rank #2
Changing a value in one shell never rewrites the environment of its parent, of a sibling terminal, or of an application that is already running. A running program keeps the environment it received at launch. Restart the program, or start a new process through the path that should provide the value, to see a change.
Make a value persist across sessions
Persistence depends on which process needs the value. A setting that works in an interactive terminal may not reach a graphical application or a systemd service, and each of those is configured in a different place.
Shell startup files
Bash reads different startup files depending on whether it is a login shell, an interactive shell, or a non-interactive shell started by a script. Put export lines in the file that matches the shell you actually use. The INVOCATION section of man bash on your installed system lists the exact files for each case. Because distributions differ in what their default startup files source, check the file your login path reads before you edit it.
Rank #3
Login environment and /etc/environment
On systems that use PAM, /etc/environment can supply variables at login. It is a system-wide file, and it does not perform shell expansion, so write plain NAME=value lines. Whether it is read, and when, depends on the distribution and on the login path, so verify the result with a new login rather than assuming it.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →systemd user services
Services started by the systemd user instance receive variables from environment.d configuration. Per-user files live in ~/.config/environment.d/ and use the .conf extension. These assignments apply to services started by the user manager. They do not change the environment of your terminal, and they do not necessarily reach programs started through other paths. To see what the user manager will pass on, run:
systemctl --user show-environment
After editing these files, log out and back in so the user manager rereads them, then run the command again.
A single systemd unit
When one service needs a value, set it in that unit rather than in a global file. Open a drop-in override for the unit, then add the setting under [Service]:
systemctl --user edit myapp.service
[Service]
Environment=APP_MODE=production
EnvironmentFile=-%h/.config/myapp/env
Apply the change with systemctl --user daemon-reload and then systemctl --user restart myapp.service. The EnvironmentFile= line reads a file of NAME=value entries; the leading dash makes the file optional, so the unit starts even if it is missing. For a system service, use sudo systemctl edit with the unit name instead of the --user form.
Which mechanism to choose
| Need | Mechanism | Who inherits the value | Takes effect in |
|---|---|---|---|
| One program run | NAME=value command |
That command only | The next invocation |
| Current shell and its children | export NAME=value |
The shell and commands it starts later | Immediately, for new children |
| Interactive or login shells | Bash startup files | Shells that read the file | A new shell session |
| Login sessions on PAM systems | /etc/environment |
Processes started in the login session | A new login; behavior varies by distribution |
| systemd user services | ~/.config/environment.d/*.conf |
Services started by the user manager | After logging out and back in |
| One specific service | Environment= or EnvironmentFile= in the unit |
Only that unit’s processes | After daemon-reload and a restart |
When two places set the same name, the more specific one usually wins for the process it governs. A unit’s Environment= line overrides a value that the user manager would otherwise pass to that unit, and an export in your shell does not override a value a service receives from systemd.
Check where a value is missing
- Find the launcher. Identify the process that starts the program: your terminal shell, a desktop launcher, a cron job, or a systemd unit.
- Inspect the value in that context. Run
printenv NAMEfrom the same shell or wrapper that launches the program. For a running service, find its process ID withsystemctl --user status myapp.service, then runtr ' ' 'n' < /proc/PID/environ | grep NAME. Reading another user’s process requires root. - Check the configured source. For a unit, run
systemctl --user show myapp.service -p Environment. For the user manager, runsystemctl --user show-environment. - Test a fresh process. Restart the service or log in again. Existing processes keep the environment they were given at launch.
- Quote values carefully. Use single quotes for values containing spaces or shell metacharacters in shell syntax. In
environment.dand unit files, follow the syntax those tools document rather than shell rules.
Handle secrets with care
Environment variables are visible to the process that owns them and, depending on permissions, to other users who can read its process information. They also end up in shell history, unit files, and configuration files that may be committed to version control. Avoid placing passwords or tokens in broadly inherited environments. Prefer a file with restrictive permissions, referenced through EnvironmentFile=, or a dedicated secret store, and decide who may read each file before adding a value. The upstream documentation covers how environments are passed, but it is not a complete security review of your system.
Sources and version notes
The behavior described here comes from the GNU Bash Reference Manual, the POSIX specification of the export utility, and the systemd documentation for user services and unit environments. Those documents are maintained over time, so use the copies installed on your system (man bash, man environment.d, man systemd.exec) when a detail matters. No single startup file is guaranteed to reach every shell, distribution, graphical application, and service, so confirm the result in the launch path you care about.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.

