System and users
printenv
Print all environment variables, or the values of the ones you name.
printenv [-0] [VARIABLE...]
printenv prints the environment it received. With no arguments the output looks like
env's; with names it prints only their values, one per line, and its exit status says
whether every name was found. That makes it a clean way to check for a variable in a script
without the ambiguity of echo "$VAR", which prints an empty line both for an empty variable
and for one that does not exist.
Because it is a separate program, printenv sees only exported variables, exactly what any
child process would see. That is its most useful property when debugging: if printenv FOO
shows nothing, the program you are about to start will not see FOO either, however echo
$FOO looks in your shell.
Examples
Print the whole environment
printenv
SHELL=/bin/bash EDITOR=vi PWD=/home/dev/demo LOGNAME=dev TZ=UTC HOME=/home/dev LANG=C.UTF-8 COLUMNS=80 TERM=dumb USER=dev SHLVL=0 PATH=/usr/local/bin:/usr/bin:/bin _=/usr/bin/printenv
Every exported variable as NAME=value, in no particular order.
Print one variable's value
printenv HOME
/home/dev
Only the value is printed, without the name, so it can be captured with $(...).
Print several values
printenv USER SHELL TZ
dev /bin/bash UTC
One value per line, in the order you asked for.
Ask for a variable that is not set
printenv DATABASE_URL; echo "exit: $?"
exit: 1
Nothing is printed and the exit status is 1. When several names are given, the status is 1 if any of them is missing.
Stop a script when a required variable is missing
for v in HOME API_TOKEN; do
printenv "$v" >/dev/null || { echo "error: $v is not set" >&2; exit 1; }
done
echo "all set"
error: API_TOKEN is not set
The exit status drives the check, so an empty-but-set variable still counts as present.
API_TOKEN is missing here, so the loop stops with status 1.
See the difference between a shell variable and an exported one
region=eu-west
printenv region || echo "not exported yet"
export region
printenv region
not exported yet eu-west
A plain assignment creates a shell variable that child processes, including printenv,
cannot see. After export it becomes part of the environment.
Show variables whose names match a pattern
printenv | grep -E '^(LANG|LC_|TZ)'
TZ=UTC LANG=C.UTF-8
Filtering on ^NAME matches names only, not values. Here: the locale and time zone settings
that affect sorting and dates.
Check what a .env file adds
cat .env
set -a; . ./.env; set +a
printenv API_URL DEBUG
API_URL=http://localhost:8080 DEBUG=false http://localhost:8080 false
set -a exports every variable assigned while it is on, so sourcing a KEY=value file
makes the values visible to printenv and to any program started afterwards.
Common pitfalls
Writing
printenv $HOME. The argument is a variable name:printenv HOME. With$, the shell substitutes the value and printenv looks for a variable called/home/dev.Concluding a variable is unset because
printenvshows nothing, when it is only unexported.declare -p NAMEshows shell variables too.Using
printenvto check a variable that a script sets for itself. Variables set in the current shell only appear afterexport.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
BSD and macOS
printenvaccept only one variable name and have no-0; GNU accepts several. For portability, call it once per variable.
Options worth knowing
A selection, described in our own words. For the full list, see printenv(1) or printenv --help.
| Option | What it does |
|---|---|
-0, --null | End each output entry with NUL instead of a newline. |
--help | Print usage and exit. |
--version | Print the coreutils version and exit. |
Related
envPrint the environment, or run a command with a modified environment.exportMark shell variables (or bash functions) to be passed to every program the shell starts.setTurn shell options such as -e, -u, -x and pipefail on or off, and replace the positional parameters.echoPrint its arguments separated by spaces, followed by a newline.declareCreate variables with attributes (array, associative array, integer, read-only, exported), or show how variables are defined.- Environment variablesHow export passes variables to child processes, the one-command NAME=value prefix, loading .env files, and why a child cannot change its parent.
- VariablesAssigning and reading shell variables, the no-spaces rule, braces, unset vs empty, scope, readonly, and the special variables bash sets for you.