VMware ESXi and vSphere Cluster Management
env Command: View, Set, and Run Programs with Environment Variables
Learn how to use the Unix and Linux env command to inspect environment variables, run commands with temporary settings, create minimal environments, and troubleshoot PATH and shell scope.
The Unix and Linux env command displays a process environment or starts a command with a modified environment. It is useful for inspecting inherited settings, testing how programs behave under different conditions, and launching commands with carefully selected variables.
An environment variable is a named value made available to a process. A process environment is the complete set of variable assignments associated with that process. When a process starts a child process, the child normally receives a copy of the parent's environment. The child can change its own copy without changing the parent.
What env Changes and What It Does Not
env modifies the environment of the command it launches. It cannot permanently change the environment of the shell that invoked it, because a child process cannot directly modify its parent process.
Environment variables are different from shell variables, command-line arguments, and configuration files:
- A shell variable exists inside the shell. It becomes available to external child processes only when exported.
- An environment variable is passed to a process and is commonly inherited by programs that process launches.
- Command-line arguments are values supplied after a command name, such as
file.txtincat file.txt. They are not environment variables. - Configuration files are files read by a shell or application. Their settings may create variables, but a configuration file is not itself an environment.
Displaying the Environment
Run env without operands to print the environment inherited by the current shell:
env
Each line normally uses the NAME=VALUE format:
PATH=/usr/local/bin:/usr/bin:/bin
HOME=/home/alex
LANG=en_US.UTF-8
The exact output varies by user, shell, login method, operating system, session manager, and current process. Do not assume that another machine has the same variables or values.
To inspect one variable while using another command to filter the output:
env | grep '^PATH='
Here, grep is a separate command receiving the output through a pipe. For a direct lookup, many systems also provide printenv:
printenv PATH
Running a Command with Temporary Assignments
The general form is:
env NAME=VALUE command [arguments]
For example, this runs date with the C locale:
env LANG=C date
Multiple assignments can precede the command:
env LANG=C LC_ALL=C EDITOR=vi some-command
The assignments affect some-command and any child processes it starts. They do not remain in the invoking shell after the command finishes.
Quote values when they contain spaces, shell metacharacters, command substitutions, or an empty value:
env GREETING='hello world' sh -c 'printf "%s\n" "$GREETING"'
env PATTERN='a; b' sh -c 'printf "%s\n" "$PATTERN"'
env EMPTY='' sh -c 'printf "length=%s\n" "${#EMPTY}"'
Quoting is processed by the shell before env receives the assignment. Single quotes preserve the value literally; double quotes still allow shell variable expansion and command substitution.
Starting with an Empty or Reduced Environment
Use -i, also commonly written --ignore-environment, to discard inherited variables before applying new assignments:
env -i PATH=/usr/bin:/bin HOME="$HOME" sh
This is useful for reproducible tests, diagnosing configuration leakage, and controlled automation. Clearing the environment can also remove variables an application needs, including PATH, HOME, TERM, locale settings, and proxy settings.
If PATH is absent, env may be unable to find a command by name. Supply a suitable path or use an absolute pathname:
env -i /usr/bin/printf '%s\n' 'minimal environment'
env -i PATH=/usr/bin:/bin command-name
Removing Variables
On implementations supporting it, -u NAME or --unset=NAME removes an inherited variable before launching the command:
env -u HTTP_PROXY curl https://example.com
More than one variable can be removed by repeating the option:
env -u HTTP_PROXY -u HTTPS_PROXY command-name
Unsetting a variable is different from assigning an empty value:
env -u EDITOR command-name
env EDITOR='' command-name
In the first case, EDITOR is absent. In the second, it exists with an empty value. Programs may treat those cases differently.
Command Lookup and PATH
PATH is a colon-separated list of directories searched for executable commands. When env is given a command name rather than a pathname, the command is normally found through PATH:
env PATH=/usr/bin:/bin command-name
A changed or empty PATH can select a different executable or prevent lookup entirely. In minimal or security-sensitive environments, an absolute path avoids ambiguity:
env -i PATH=/usr/bin:/bin /usr/bin/printf '%s\n' 'controlled command'
Inspect which executable a shell would find with:
command -v python3
Remember that env itself must first be found by the shell unless you invoke it by pathname.
Common Environment Variables
| Variable | Typical role | Example impact | Cautions |
|---|---|---|---|
PATH | Directories searched for executables | Controls which command is selected | Order and untrusted directories can create security risks |
HOME | User's home directory | Applications locate user configuration | May be absent or unsuitable in service accounts |
LANG | Default language and locale | Changes messages, formatting, and character handling | Availability depends on installed locales |
LC_ALL | Overrides locale categories | Can force consistent output for tests | Usually should be set deliberately, not globally without reason |
TERM | Terminal type | Controls terminal capabilities for interactive programs | Incorrect values can break screen formatting |
EDITOR | Preferred text editor | Tools may open the selected editor | Programs differ in whether they honor it |
TMPDIR | Preferred temporary-file directory | Changes where temporary files are created | The directory should exist and have appropriate permissions |
HTTP_PROXY and HTTPS_PROXY | Proxy settings for some network tools | Routes requests through a proxy | Values may expose network details or cause unexpected routing |
Other frequently encountered variables include USER or LOGNAME, SHELL, and PWD. Availability and meaning are platform- and program-specific; a variable's presence does not guarantee that every program uses it.
Locale Precedence
Locale selection commonly starts with LANG, while a matching category variable such as LC_TIME or LC_MESSAGES takes precedence for that category. LC_ALL overrides all category variables and LANG. This is why env LANG=C LC_ALL=C command is often used when scripts need predictable text output.
env in Interpreter Directives
A shebang is the #! line at the beginning of an executable script. A common form uses /usr/bin/env to locate an interpreter through PATH:
#!/usr/bin/env python3
print("Hello")
After the script is made executable, the operating system starts /usr/bin/env; env searches PATH for python3 and starts the selected interpreter. This can be convenient when interpreter locations differ between systems.
It also introduces portability and security considerations. The selected interpreter depends on PATH, and an unexpected directory earlier in PATH can select the wrong program. Use a controlled PATH or a fixed interpreter pathname when the interpreter must be exact.
Some modern implementations support -S or --split-string in a shebang, allowing multiple interpreter arguments:
#!/usr/bin/env -S python3 -u
This feature is not universally supported, and operating systems differ in how shebang arguments are passed. Use it only when the target systems provide compatible support; otherwise use a wrapper script or a simpler shebang.
Shell Interaction and Scope
These two forms often produce a similar one-command scope:
env MODE=test command-name
MODE=test command-name
The first explicitly asks env to create the assignment. The second is shell syntax: the shell places the assignment in the environment of that command when it launches an external program. Neither normally leaves MODE set afterward.
To make a shell variable available to later external commands, export it:
MODE=test
export MODE
command-name
printf '%s\n' "$MODE"
Use unset to remove a variable from the current shell:
unset MODE
| Command or syntax | Primary purpose | Changes parent shell? | Notes |
|---|---|---|---|
env | Display or construct an environment for a command | No | Can add, remove, or clear variables for the child command |
printenv | Display environment variables | No | Often supports printing one named variable |
export | Mark a shell variable for child-process inheritance | Yes, within the current shell | A shell builtin, not generally an external program |
unset | Remove a shell variable | Yes, within the current shell | A shell builtin |
NAME=VALUE command | Set a command-specific environment value | No persistent change | Shell syntax; behavior also depends on whether the command is a builtin |
command -v command_name | Show how the shell resolves a command | No | Useful for checking PATH and aliases or functions |
Options, Implementations, and Exit Status
| Feature | Common availability | Fallback approach | Portability consideration |
|---|---|---|---|
-i | Common GNU and POSIX-style feature | Construct a controlled environment with shell tools or a wrapper | Confirm exact spelling with local documentation |
-u NAME | Common, including GNU implementations | Use a shell wrapper that avoids exporting the variable | Option syntax and long form may vary |
--help | Common on GNU systems | Use man env or local documentation | Long options are not universal |
--split-string or -S | Modern extension on some implementations | Use a wrapper or a simple shebang | Especially important for shebang portability |
| env-based shebangs | Common on Unix-like systems | Use a fixed interpreter pathname | Depends on /usr/bin/env, PATH, and shebang handling |
Common options include -i or --ignore-environment and, where supported, -u NAME or --unset=NAME. Some implementations also accept an option terminator such as -- before a command name that could otherwise be interpreted as an option. Consult the target system:
env --help
man env
When env successfully starts a command, it normally returns that command's exit status. An exit status is a numeric result, conventionally zero for success. If the requested command cannot be found or started, env reports an error and returns a nonzero status; the exact value and diagnostic can vary by implementation and failure type.
Troubleshooting
Command Not Found with env -i
If env -i command reports that the command cannot be found, clearing the environment probably removed PATH. Restore it or use an absolute pathname:
env -i PATH=/usr/bin:/bin command
env -i /usr/bin/command
Variable Missing After the Command
For example:
MODE=test env | grep '^MODE='
printf '%s\n' "$MODE"
The first command sees MODE, but the second command may print an empty value because env changed only the environment of its own child process. Use MODE=test followed by export MODE when the setting must persist in the current shell.
Unexpected Interpreter from a Shebang
For a script using #!/usr/bin/env python3, inspect the search path and selected interpreter:
printf '%s\n' "$PATH"
command -v python3
Use a controlled PATH or fixed pathname if the result is not the intended interpreter.
Different Behavior Under env -i
The program may depend on omitted variables such as HOME, PATH, TERM, locale variables, or proxy settings. Add back only one required variable at a time and compare the results.
Unsupported Options
If env -u or env -S is rejected, the installed implementation may not provide that extension. Read man env and use a portable shell-based alternative or avoid the unsupported option.
Unexpected Text, Sorting, or Dates
Differences in language, sorting, dates, or character handling often come from LANG, LC_ALL, or another LC_* variable. Inspect them and set the required locale explicitly:
env | grep -E '^(LANG|LC_)'
env LANG=C LC_ALL=C command-name
Security and Operational Cautions
- Do not treat environment variables as secure storage for secrets. Process listings, logs, crash reports, child processes, debugging tools, and service diagnostics may expose them.
- Be cautious with an untrusted
PATH.env-based commands and interpreter lines can execute an unexpected program if an attacker controls an earlier directory. - Use absolute command paths or a controlled
PATHfor privileged, automated, or deployment tasks. - For automation, prefer a minimal explicit environment when inherited settings could affect correctness, credentials, networking, locale, or file locations.
- Remember that removing a variable does not undo effects already caused by a parent process or configuration file.
Quick Reference
| Form | Meaning | Scope | Example |
|---|---|---|---|
env | Print the current environment | Read-only display | env |
env NAME=VALUE command | Run a command with an added or replaced variable | Command and its children | env LANG=C date |
env -i command | Start without inherited variables | Command and its children | env -i PATH=/usr/bin:/bin command |
env -u NAME command | Remove an inherited variable | Command and its children | env -u HTTP_PROXY curl https://example.com |
For more command-line environment practice, return to the env command reference lesson.