env prints the current environment, sets or removes variables for a single command, and can start a process with an entirely clean environment. All changes it makes are scoped to the command it launches — your current shell is never touched.
The syntax is:
bashenv [OPTIONS] [NAME=VALUE]... [COMMAND [ARGS]]
Run without arguments to print every environment variable in the current session:
bashenv
Output: SHELL=/bin/bash USER=john HOME=/home/john PATH=...
Each line is a KEY=value pair. The output is identical to printenv with no arguments. The difference: printenv is a read-only inspection tool, it can also print a single variable by name (printenv HOME). env is designed to modify the environment before launching a program.
Run a command with modified variables by placing NAME=VALUE pairs before it:
bashenv LANG=C sort unsorted.txtenv DB_HOST=localhost DB_PORT=5432 python3 app.py
The command sees those variables in its environment. Your shell’s values stay unchanged after the process exits. You can get the same result with the shell’s built-in VAR=value command syntax — env becomes necessary when you also need -i or -u, or want to be explicit about environment manipulation in scripts.
Print with a NUL separator when variable values might contain newlines:
bashenv -0 | tr '\0' '\n' | head -5
-0 (or --null) ends each entry with a NUL byte instead of a newline. This prevents ambiguous output and is compatible with tools like xargs -0.
Remove a specific variable for one command with -u (or --unset):
bashenv -u EDITOR vimenv -u LANG -u LC_ALL python3 script.py
-u is surgical — it removes only the named variables and leaves everything else in place.
Change the working directory before running the command with -C (or --chdir):
bashenv -C /var/log cat syslog | head -3
This is equivalent to cd /var/log && cat syslog but without changing your current shell’s working directory. -C requires GNU coreutils 8.28 or later — check with env --version.
The -i (or --ignore-environment) option clears the entire inherited environment before running the command:
bashenv -i bash -c 'env'
The output shows almost nothing — only PWD, SHLVL, and _, which the shell sets internally. Everything the parent shell normally passes along (PATH, HOME, LANG, USER) is gone.
A bare - (hyphen) is shorthand for -i:
bashenv - PATH=/usr/bin bash -c 'echo $PATH'
Combine -i with explicit variables to create a minimal, controlled environment:
bashenv -i HOME=/home/john PATH=/usr/bin:/bin bash -c 'echo $HOME'
Use this to verify that a script does not secretly depend on variables it does not set itself. In security-sensitive contexts, it also prevents child processes from inheriting variables like AWS_SECRET_ACCESS_KEY or database credentials from the parent shell.
The most common use of env in scripts is the portable shebang:
bash#!/usr/bin/env bash
The kernel passes bash to /usr/bin/env, which searches PATH for the executable and runs it. This is more portable than #!/bin/bash — on FreeBSD, bash lives at /usr/local/bin/bash, not /bin/bash. The same pattern works for other interpreters:
bash#!/usr/bin/env python3#!/usr/bin/env node
To pass arguments to the interpreter in a shebang, use -S (split string), available in GNU coreutils 8.30+:
bash#!/usr/bin/env -S python3 -u
Without -S, the kernel treats python3 -u as a single argument and the interpreter launch fails.
Use env to inspect the current environment, env VAR=value command for scoped changes, -u to surgically remove a variable, -i for a clean slate, and #!/usr/bin/env for portable shebangs. Leave a comment below if you run into any issues.