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 tr Command: Translate and Delete Characters

Linux tr Command: Translate and Delete Characters

Learn how to translate and Delete Characters with the Linux tr command, including practical examples, key options, and important precautions.

Linux pgrep Command: Find Process IDs by Name or Criteria

Linux pgrep Command: Find Process IDs by Name or Criteria

Learn how to find Process IDs by Name or Criteria with the Linux pgrep command, including practical examples, key options, and important precautions.

Linux history Command: Review and Reuse Shell Command History

Linux history Command: Review and Reuse Shell Command History

Learn how to use the Linux history command to review, search, reuse, and manage shell command history, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux Tutorial / PID and PPID Explained: Find and Manage Processes

Linux Tutorial / PID and PPID Explained: Find and Manage Processes

Understand what PID and PPID mean, inspect parent-child process relationships with ps and pgrep, and safely terminate a process you started yourself.

Linux ssh-copy-id Command: Install a Public Key on a Remote Account

Linux ssh-copy-id Command: Install a Public Key on a Remote Account

Learn how to install a Public Key on a Remote Account with the Linux ssh-copy-id command, including practical examples, key options, and important precautions.

Linux apropos Command: Search Commands by Description

Linux apropos Command: Search Commands by Description

Learn how to use the Linux apropos command to find relevant manual pages by searching description keywords, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux umask Command: Control Default File Permissions

Linux umask Command: Control Default File Permissions

Learn how to control Default File Permissions with the Linux umask command, including practical examples, key options, and important precautions.

Linux whatis Command: Show One-Line Command Descriptions

Linux whatis Command: Show One-Line Command Descriptions

Learn how to use the Linux whatis command to display concise descriptions of commands and manual pages, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux chgrp Command: Change a File's Group

Linux chgrp Command: Change a File's Group

Learn how to change a File's Group with the Linux chgrp command, including practical examples, key options, and important precautions.

Linux basename Command: Extract the Final Component of a Path

Linux basename Command: Extract the Final Component of a Path

Learn how to use the Linux basename command to remove directory prefixes and optional suffixes from path strings, with essential options, practical examples, output interpretation, and common troubleshooting tips.