Linux env Command: Display Variables and Run Commands with a Custom Environment

env is a GNU Coreutils command used to check environment variables or to execute a command while adding, modifying, or removing some environment variables. It is especially useful when you want to pass a different environment to a specific process without changing the current shell directly.

When run without arguments, it prints the currently passed environment, but if you only need to view it, printenv makes the intention clearer. The main purpose of env is to "execute a command in a modified environment."

What is the env command?

A process inherits a set of environment variables from its parent process. env creates a new environment based on this set by adding or removing variables and then executes the specified command. The changes can be passed to the executed child process and its children, but the original shell's environment remains unchanged.

Basic Syntax

env [options] [name=value]... [command [arguments]...]

If no command is specified, it prints the resulting environment.

env
env | sort

Since environment variables may include secrets, do not directly post the full output in posts, support requests, or public logs.

Setting environment variables for a single command

env APP_ENV=production ./start.sh
env LANG=C sort names.txt

APP_ENV and LANG apply only to the environment of the command being executed. After the command finishes, the same variables in the current shell will not be newly created or changed.

printenv APP_ENV

You can specify multiple variables in order from left to right.

env HOST=127.0.0.1 PORT=8080 DEBUG=1 ./server

Comparison between assignment statements in the current shell and env

In POSIX-style shells, you can set the environment for a command by directly prefixing it with name=value.

LANG=C sort names.txt
env LANG=C sort names.txt

In simple cases, the results of the two forms are similar. env is useful when you need additional features like clearing the environment, removing variables, changing the working directory, or searching for the script interpreter.

Running with a cleared environment using -i

env -i /usr/bin/printenv

-i or --ignore-environment ignores the existing environment and starts from an empty one. It is useful for reproducibility testing or finding hidden environment dependencies, but it may also remove PATH, HOME, locale, and authentication-related variables.

You can explicitly re-add only the necessary variables to run.

env -i PATH=/usr/bin:/bin HOME="$HOME" LANG=C /usr/bin/env

If PATH is missing, command lookup may fail, so use absolute paths or specify the required paths together.

Removing only specific variables -u

env -u HTTP_PROXY curl https://example.com
env --unset=DEBUG ./start.sh

-u name or --unset=name removes the specified variable from the resulting environment. It can be used to check the effect of proxy, debug, or test variables on program behavior.

Setting a variable to an empty string is different from removing it.

env DEBUG= ./start.sh
env -u DEBUG ./start.sh

Depending on the program, "variable exists but the value is empty" and "variable does not exist" can be handled differently.

Running in a different directory -C

env -C /srv/app ./start.sh
env --chdir=/srv/app APP_ENV=production ./start.sh

The GNU env -C or --chdir changes to the specified directory and then executes the command. The current shell's working directory does not change. Since this option is a GNU extension, check for support in scripts that require portability.

Frequently used options

Option Description
-i, --ignore-environment Start with a clean environment ignoring the existing environment.
-u name, --unset=name Removes the specified variable from the environment.
-C directory, --chdir=directory Changes to the specified directory before executing the command.
-S string, --split-string=string Splits the string into multiple arguments. Primarily used to pass multiple arguments in a shebang.
-0, --null When printing the environment, separates entries with a NUL character instead of a newline.

Supported options may vary depending on the Coreutils version. Please check both your distribution's env --help and the official manual.

Using /usr/bin/env in the first line of a script

In a script's shebang, you can have the interpreter found via PATH.

#!/usr/bin/env python3

This is convenient in development environments where the interpreter may be installed in different paths on different systems. However, since it executes the first program found in the current PATH, for system services where security and reproducibility are important, a verified absolute path may be more appropriate.

Passing multiple interpreter arguments

In environments where GNU Coreutils supports -S, the shebang string can be separated into multiple arguments.

#!/usr/bin/env -S python3 -I

-S is not supported by env on all operating systems. Check the target distribution system, and if high portability is required, consider handling interpreter arguments inside the script.

Differences between shell variables and environment variables

Just because you create a variable in the shell does not mean it is automatically passed to child processes.

LOCAL_ONLY=value
printenv LOCAL_ONLY

export LOCAL_ONLY
printenv LOCAL_ONLY

Only variables that are exported are included in the environment of the newly executed program. env operates based on the environment passed to it, not the entire current shell variables.

Comparison between env and printenv

Category env printenv
Main Purpose Execute command in the modified environment Check the value of an environment variable
Print the entire environment Possible if the command is omitted Possible if the variable name is omitted
Check a specific variable Since there is no dedicated format, a filter is required. It is directly queried like printenv HOME.
Add or remove variables Supported. Not supported.
Execute command Supported. Not supported.

Precautions for security and operation

  • Do not log the entire environment including tokens, passwords, and private key paths.
  • You should consider the possibility of exposing secrets to shell history or process information if you write secret values directly in env NAME=VALUE command.
  • Using env -i can result in different behavior as certificate paths, locale, and proxy variables may be missing.
  • The /usr/bin/env in shebang is affected by PATH, so make sure you can trust the executor and the environment.
  • For service environments, use the explicit environment setting functions of the service manager whenever possible.

Frequently Asked Questions

Do variables set with env remain in the current terminal?

No. env NAME=VALUE command only changes the environment for the executed command and does not modify the parent shell's variables.

What is the difference between env and export?

export marks the current shell variable to be passed to child processes executed later. env is suitable for setting up an environment for a single command execution.

The command cannot be found in env -i.

This may be because the existing PATH has also been removed. Use the absolute path of the executable or explicitly set the required PATH.

Related articles and official documentation

More in This Category
Linux tracepath Command: Trace a Network Path and Path MTU

Linux tracepath Command: Trace a Network Path and Path MTU

Learn how to trace a Network Path and Path MTU with the Linux tracepath command, including practical examples, key options, and important precautions.

Linux modinfo Command: Inspect Kernel Module Details

Linux modinfo Command: Inspect Kernel Module Details

Learn how to inspect Kernel Module Details with the Linux modinfo command, including practical examples, key options, and important precautions.

Linux type Command: Identify How a Command Is Resolved

Linux type Command: Identify How a Command Is Resolved

Learn how to use the Linux type command to identify aliases, functions, built-ins, keywords, and executable paths, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux Tutorial / Search and Process Text with grep, sort, uniq, cut, and wc

Linux Tutorial / Search and Process Text with grep, sort, uniq, cut, and wc

Practice searching, sorting, grouping, extracting, and counting text with grep, sort, uniq, cut, and wc, including reproducible output and key caveats.

Linux Tutorial / Hard Links vs. Symbolic Links in Linux: Differences and Examples

Linux Tutorial / Hard Links vs. Symbolic Links in Linux: Differences and Examples

Compare hard and symbolic links through inode and path behavior, then create both kinds of link and observe what happens when the original name changes.

Linux w Command: Show Logged-In Users and Their Processes

Linux w Command: Show Logged-In Users and Their Processes

Learn how to show Logged-In Users and Their Processes with the Linux w command, including practical examples, key options, and important precautions.

Linux sort Command: Sort Text Lines

Linux sort Command: Sort Text Lines

Learn how to sort text lines with the Linux sort command, including practical examples, key options, and important precautions.

Linux env Command: Display Variables and Run Commands with a Custom Environment

Linux env Command: Display Variables and Run Commands with a Custom Environment

Learn how to use the Linux env command to display environment variables or run a command with temporary variable values, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux dd Command: Copy and Convert Data by Blocks

Linux dd Command: Copy and Convert Data by Blocks

Learn how to copy and convert files or block devices with Linux dd, choose block sizes and ranges, display progress, verify results, and avoid overwriting the wrong device.

Linux info Command: Browse GNU Documentation

Linux info Command: Browse GNU Documentation

Learn how to use the Linux info command to browse hierarchical GNU manuals and navigate Info nodes, with essential options, practical examples, output interpretation, and common troubleshooting tips.