I am on LinuxMint (have tried CentOS too) and have been trying to use the printenv command for a environment variable which may or may not exist. So I want it to print the value of that name if it is present, else print nothing but return with a exit code 0.

However, if I invoke it with a non-existent environment name, it exits with error code 1. The man pages or the help for printenv doesn't say anything about this behaviour.

Here's how I tried it:

> /usr/bin/printenv foo

That just returns, then I do:

> echo $?

which returns:


The version of printenv is:

printenv (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by David MacKenzie and Richard Mlynarik.

Does anyone have an alternate way to achieve what I'm after? Ultimately, I just need to set a bash variable to contain the value of an environment variable if that environment variable exists, else have that bash variable empty:

mybashv=`printenv foo`

The info documentation for printenv says the following about exit codes:

 0 if all variables specified were found
 1 if at least one specified variable was not found
 2 if a write error occurred

This looks consistent with what you observed.

If I understand correctly, you want to hide this status code. For any command, this can be achieved by appending || true, e.g.:

$ var=`printenv foo || true`
$ echo $?
  • Thank you! That || true option worked. As for the documentation you pasted, can you tell me where/how you found it? I checked man printenv and printenv --help and even looked online and did not find that information. – Watson Dec 1 '16 at 14:01
  • @Watson see the manual or info '(coreutils) printenv invocation' (as documented in the manpage). – Stephen Kitt Dec 1 '16 at 14:11

Returning a non-zero exit status (failure) when failing to print the content of an environment variable sounds like the right thing to do to me. That matches the behaviour of the tcsh builtin of the same name and of historical implementations on BSDs.

Not doing that would make it difficult to differentiate between a variable that is set to an empty value and one that is not set.

If you want to avoid the effect of set -e/set -o errexit, use:

var=$(printenv VAR) || : Do not care if it fails


if var=$(printenv VAR); then
  if [ -z "$var" ]; then
    echo "VAR is set but empty or consists only of newline characters"
    echo "VAR is set and non-empty"
  echo "VAR is not in the environment"

Also note that all shells initialise shell variables from the corresponding environment variables (for those that can be mapped to shell variables, and some shells strip others), so you could as well use $VAR in your script to refer to their value (note however that in the Bourne, csh or tcsh shells (the only shells where one may still want to use those `...` of yours), the value of the shell and env var may diverge if you modify the shell variable without exporting it (or assigning it with setenv for (t)csh)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.