'It works in my terminal but not when the app runs elsewhere' is almost always an environment variable problem. Understanding PATH and shell config files turns this from a recurring mystery into something you can actually diagnose and fix.
3 min read
An environment variable is a named value available to every process running in a given shell session — configuration that lives outside any specific program's own code, readable by whatever process needs it:
$ echo $HOME
/home/alice
$ echo $USER
alice
$ export API_KEY="secret-value" # set a new one for this session
$ echo $API_KEY
secret-valuePATH is a specific, critical environment variable: a list of
directories the shell searches, in order, when you type a command name,
looking for a matching executable file:
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/home/alice/.local/binWhen you type python, the shell checks each directory in PATH, in order,
until it finds an executable file named python — and runs the first one
it finds. This is the direct, mechanical explanation behind "command not
found" (no directory in PATH contains that executable) and behind "why is
the wrong version of this tool running" (an earlier directory in PATH
contains an older or different version than the one you actually intended).
Files like ~/.bashrc or ~/.zshrc (depending on which shell you use) run
automatically every time you open a new terminal session, and are where
persistent configuration lives — custom PATH additions, aliases, exported
environment variables you want available every time, not just for one
session:
# in ~/.bashrc or ~/.zshrc
export PATH="$HOME/.local/bin:$PATH" # add a directory to the front of PATH
alias ll="ls -la" # a shortcut: typing "ll" runs "ls -la"
export EDITOR="vim" # tools that need a default text editor check thisChanges to these files only take effect in new terminal sessions, or after
running source ~/.bashrc to reload the current one manually — editing the
file alone doesn't retroactively affect a session that's already running.
A scheduled task (cron) or a CI pipeline typically runs in a minimal
environment that does not automatically load your interactive shell's
~/.bashrc the way opening a normal terminal does — meaning any PATH
additions or environment variables set only in that file simply aren't
present there. This is the actual, mechanical explanation behind a script
that runs perfectly when you test it manually but fails mysteriously when
run by a scheduler or a CI job — not a different bug, the same environment-
variable gap, showing up in a different, less obvious context.
Prefixing a single command with a variable assignment sets it just for that one invocation, without affecting the wider session at all:
$ DEBUG=true python app.py # DEBUG is only set for this one runThis is a genuinely useful pattern for testing a one-off configuration change without permanently altering your shell's exported environment.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What does the PATH environment variable actually control?
2. Why does a script that works fine when run manually sometimes fail when run via cron or CI?
3. What does prefixing a command like `DEBUG=true python app.py` accomplish?
Linux & the Command Line