3

For some reason, my system sets an environment variable with no name. This can be seen in the output from printenv as a line containing only = and causes problems for Python (more specifically the os.environ object).

How do I unset this environment variable? Is there any other workaround (e.g. prevent the variable to be set in the first place)?

To reproduce do e.g. env -i printenv, or for the Python problem do env -i = python -c "import os; os.environ.clear()"

  • exec env -u '' "$SHELL" will remove it. – Stéphane Chazelas Jan 10 '15 at 23:52
  • @StéphaneChazelas: does not work for me, env: cannot unset ‘’: Invalid argument – Anders Lundstedt Jan 11 '15 at 0:05
  • 2
    The exec bash -c 'exec "$SHELL"' since bash strips that. – Stéphane Chazelas Jan 11 '15 at 0:16
  • It's a bug in Python's posix.unsetenv. POSIX doesn't mandate compliant OSes to support empty names, but Python should support them on OSes that do. – Gilles Jan 11 '15 at 22:20
  • There's a bug env from GNU coreutils as well, since it can set but not unset a variable with an empty name. – Gilles Jan 11 '15 at 22:26
2

Environment variables aren't supposed to have an empty name, so many utilities don't support them.

The env command from GNU coreutils supports setting the environment variable with an empty name but not unsetting it. That's a bug.

$ env '=wibble' env |grep wibble                                 
=wibble
$ env '=wibble' env -u '' env
env: cannot unset `': Invalid argument

Common shells can't unset the empty name either. That's ok, since the empty name isn't supposed to be used as an environment variable, and can't be used as a shell variable. Zsh is the only buggy one in the lot: it pretends to do the job but in fact does nothing.

$ env '=wibble' dash -c 'unset ""'
dash: 1: unset: : bad variable name
$ env '=wibble' bash -c 'unset ""'
bash: line 0: unset: `': not a valid identifier
$ env '=wibble' ksh -c 'unset ""'
ksh[1]: unset: : invalid variable name
$ env '=wibble' mksh -c 'unset ""'
mksh: : is read only
$ env '=wibble' posh -c 'unset ""'
posh: unset:  is read only
$ env '=wibble' zsh -c 'unset ""'
$ env '=wibble' zsh -c 'unset ""; env' | grep wibble
=wibble

Python, as you've noticed, bugs out when it finds the empty name for an environment variable.

Perl has no such problem, so it may be a solution for you. Note that you have to execute a new shell to use an external process to change the environment.

perl -e 'delete $ENV{""}; exec $ARGV[0] @ARGV' "$SHELL" "-$-"
0

You can do:

import os
for k in os.environ.keys():
     print repr(k)
     del os.eniviron[k]
print os.environ
os.environ.clear()

I am not sure why a direct os.environ.clear() throws the error, I started the above for loop code to see if I could find the key causing the problem. Please not that you have to specify .keys(), just iterating using for k in os.environ: will give an error because you change the dictionary over which keys you are iterating (.keys() creates a copy).

  • 1
    Does not work for me, using os.environ methods seems to go via the same system calls as e.g. env -u. However it seems to work to simply remove the key from the underlying dictionary. In Python 2: if "" in os.environ.data: del os.environ.data[""], in Python 3: if b"" in os.environ._data: del os.environ._data[b""]. – Anders Lundstedt Jan 11 '15 at 0:30

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.