env Command in Linux: Show and Set Environment Variables

By 

Published on

7 min read

Using the env command to show and set environment variables in Linux

When you need to run a program with a different set of variables, test a script in a clean environment, or write a shebang line that works across systems, the env command is the right tool. It prints the current environment, sets or removes variables for a single command, and can even start a process with no inherited variables at all.

This guide covers how to use the env command with practical examples for everyday tasks.

env Syntax

txt
env [OPTIONS] [NAME=VALUE]... [COMMAND [ARGS]]

When called without arguments, env prints every environment variable in the current session, one per line. When followed by NAME=VALUE pairs and a command, it runs that command with the specified variables added or changed without affecting the current shell.

The simplest use of env is printing the full environment:

Terminal
env
output
SHELL=/bin/bash
USER=john
HOME=/home/john
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TERM=xterm-256color
XDG_SESSION_TYPE=tty
EDITOR=vim

Each line is a KEY=value pair. This is identical to what printenv shows with no arguments. The difference between the two commands becomes clear when you start passing options: printenv is designed for inspecting variables, while env is designed for modifying the environment before launching a program.

By default, env separates each variable with a newline character. If variable values contain newlines themselves, the output becomes ambiguous. The -0 (or --null) option ends each entry with a NUL byte instead:

Terminal
env -0 | tr '\0' '\n' | head -5

This is useful when piping environment data into tools that expect NUL-delimited input, such as xargs with its -0 flag.

Run a Command with Modified Variables

The most practical feature of env is launching a command with variables changed for that command only. Place NAME=VALUE pairs before the command:

Terminal
env LANG=C sort unsorted.txt

This runs sort with LANG set to C, which forces byte-order sorting regardless of the system locale. The current shell’s LANG value stays unchanged after the command finishes.

You can set multiple variables at once:

Terminal
env DB_HOST=localhost DB_PORT=5432 python3 app.py

The application sees DB_HOST and DB_PORT in its environment, but those variables do not persist in your shell session after the process exits.

Tip
You can achieve the same result with the shell’s built-in VAR=value command syntax (for example, LANG=C sort unsorted.txt). The env command is useful when you need additional options like -i or -u, or when you want to be explicit about environment manipulation in scripts.

Run a Command in a Clean Environment

The -i (or --ignore-environment) option clears the entire inherited environment before running the command. Only the variables you explicitly set on the command line will be present:

Terminal
env -i bash -c 'env'
output
PWD=/home/john
SHLVL=1
_=/usr/bin/env

The output shows almost nothing. The shell itself sets a few internal variables (PWD, SHLVL, _), but everything the parent shell normally passes along (PATH, HOME, LANG, USER) is gone.

This is useful for testing whether a script depends on variables it does not set itself. You can combine -i with explicit variables to create a minimal, controlled environment:

Terminal
env -i HOME=/home/john PATH=/usr/bin:/bin bash -c 'echo $HOME; echo $PATH'
output
/home/john
/usr/bin:/bin

A bare - (hyphen) works as a shorthand for -i:

Terminal
env - PATH=/usr/bin bash -c 'echo $PATH'

Unset a Variable for a Command

The -u (or --unset) option removes a specific variable from the environment before running the command:

Terminal
env -u EDITOR vim

This launches vim without the EDITOR variable in its environment. Other variables remain untouched. You can unset multiple variables by repeating -u:

Terminal
env -u LANG -u LC_ALL python3 script.py

The difference from -i is that -u is surgical: it removes only the named variables and leaves everything else in place.

Change Directory Before Running a Command

The -C (or --chdir) option changes the working directory before executing the command:

Terminal
env -C /var/log cat syslog | head -3

This is equivalent to running cd /var/log && cat syslog, but without affecting the current shell’s working directory. It is a convenient way to run a command in another directory from within a script or one-liner.

Info
The -C option requires GNU coreutils 8.28 or later. Check your version with env --version.

Using env in Shebangs

One of the most common uses of env is in shebang lines at the top of scripts:

sh
#!/usr/bin/env bash
echo "Hello from Bash"

When the kernel encounters #!/usr/bin/env bash, it runs /usr/bin/env with bash as its argument. env then searches the PATH for the bash executable and runs it. This is more portable than hardcoding #!/bin/bash, because bash is not always located in /bin on every system (for example, on FreeBSD it is typically at /usr/local/bin/bash).

The same pattern works for other interpreters:

sh
#!/usr/bin/env python3
sh
#!/usr/bin/env node

On systems with GNU coreutils 8.30 or later, you can pass arguments to the interpreter using the -S (split string) option:

sh
#!/usr/bin/env -S python3 -u

Without -S, the kernel treats python3 -u as a single argument. The -S option tells env to split the string into separate arguments before executing.

env Options

  • -i, --ignore-environment - Start with an empty environment
  • -u NAME, --unset=NAME - Remove NAME from the environment
  • -C DIR, --chdir=DIR - Change working directory to DIR before running the command
  • -0, --null - End each output line with a NUL byte instead of a newline
  • -S STRING, --split-string=STRING - Split STRING into separate arguments (useful in shebangs)
  • -v, --debug - Print verbose information for each processing step
  • --block-signal=SIG - Block delivery of the specified signal to the command
  • --default-signal=SIG - Reset signal handling to the default for the command
  • --ignore-signal=SIG - Set signal handling to ignore for the command

Quick Reference

For a printable quick reference, see the env cheatsheet .

CommandDescription
envPrint all environment variables
env -0Print variables with NUL separator
env VAR=value commandRun a command with a modified variable
env -i commandRun a command in a clean environment
env -i VAR=value commandRun a command with only the specified variables
env -u VAR commandRun a command with a variable removed
env -C /path commandRun a command in a different directory
#!/usr/bin/env bashPortable shebang line
#!/usr/bin/env -S python3 -uShebang with interpreter arguments

FAQ

What is the difference between env and printenv?
Both commands print environment variables when called without arguments. The difference is in their purpose: printenv is a read-only inspection tool that can print individual variables by name (printenv HOME). env is designed to modify the environment and run commands. Use printenv when you need to check a value, and env when you need to change the environment for a process.

What is the difference between env and export?
export is a shell built-in that adds a variable to the current shell’s environment permanently (until the session ends or you unset it). env sets variables only for the duration of a single command and does not affect the current shell. If you need a variable to persist for all subsequent commands in your session, use export. If you need a variable set for one command only, use env or the shell’s VAR=value command syntax.

When should I use env -i?
Use env -i when you want to verify that a script or program works without relying on inherited environment variables. It is also useful in security-sensitive contexts where you want to prevent a child process from seeing variables like AWS_SECRET_ACCESS_KEY or database credentials that exist in the parent shell.

Why use #!/usr/bin/env bash instead of #!/bin/bash?
The env-based shebang is more portable. On most Linux distributions, bash lives at /bin/bash, but on other Unix systems (FreeBSD, macOS with Homebrew, NixOS) it may be installed elsewhere. Using #!/usr/bin/env bash searches the PATH for the interpreter, so the script works regardless of where bash is installed.

Conclusion

The env command gives you fine-grained control over the environment a process sees without touching your current shell session. For a broader look at how environment and shell variables work in Linux, including persistent configuration and the PATH variable, see the guide on how to set and list environment variables .

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page