5

I'm trying to add functionality to an existing docker-entrypoint script, the creators of the image decided environment variables would have the form key.subkey=value. I didn't know it was an invalid naming scheme until I've tried to set and parse my own variables. Since their naming scheme is invalid, they are reading them like this:

while IFS='=' read -r var key
do
# parse
done < <(env)

What I want to do is mount a modified entrypoint that unsets my own "invalid" env variables after use, otherwise my variables will get caught by their regex pattern and will cause the script to exit. Because they pass in the captured variables to the binary as options.

Is there anyway I can unset invalid variables that's been forcibly set using docker's environment variables functionality ? Because when I try to do:

unset -v foo.foo-bar.setting-to-update

I get:

bash: unset: `foo.foo-bar.setting-to-update': not a valid identifier

Thank you

2
  • 1
    Hi. I think you are confusing environment variables and shell variables. Granted, the design of the Unix shell makes it quite natural to confuse them, but when you want to do something tricky like your case here you do need to understand the difference. That is, do you understand what the export shell command does? I'll add a hint: env -i bash runs a fresh copy of bash in an empty environment.
    – q.undertow
    Apr 23, 2022 at 18:46
  • Some versions of bash automatically unset environment variables whose names don't map to valid shell variable names. Exactly which bash release are you targeting? (See discussion of the above-referenced change at Why can't environment variables with dashes be accessed in bash 4.1.2?, or the outright cross-site duplicate at bash: how to unset an env variable with a hyphen?) Apr 24, 2022 at 15:42

1 Answer 1

11

This may be easier to understand without docker and other confusions. You have an environment variable with an "odd" name that you want to remove from the environment passed to a child program, but you can't use unset

eg

% env odd.variable=100 bash
bash-4.2$ env | grep odd
odd.variable=100
bash-4.2$ unset odd.variable
bash: unset: `odd.variable': not a valid identifier

The env command with the -u parameter can help:

bash-4.2$ env | grep odd
odd.variable=100
bash-4.2$ env -u odd.variable bash
bash-4.2$ env | grep odd
bash-4.2$ 

We can see that this new bash shell doesn't have the odd variable set.

You can unset multiple variables with multiple -u options.

So if we had multiple variables:

bash-4.2$ env | grep odd
odd.var2=200
odd.var3=300
odd.var1=100

Then we can remove them all

bash-4.2$ env -u odd.var1 -u odd.var2 -u odd.var3 bash
bash-4.2$ env | grep odd
bash-4.2$ 

This is easy if you know all the variable names; just list them

If you don't know the names, but you can identify a pattern (eg all variables starting "odd.") then you can build a command:

eg

to_remove=$(env | sed -n 's/^\(odd\.[^=]*\)=.*/-u \1/p')

That sed command will create the necessary -u settings

eg

bash-4.2$ env | grep odd
odd.var2=200
odd.var3=300
odd.var1=100
bash-4.2$ to_remove=$(env | sed -n 's/^\(odd\.[^=]*\)=.*/-u \1/p')
bash-4.2$ echo $to_remove
-u odd.var2 -u odd.var3 -u odd.var1
bash-4.2$ env $to_remove bash
bash-4.2$ env | grep odd
bash-4.2$ 

Warning: this might break if variable names or contents have odd characters like embedded CR/LF sequences. But under normal conditions it should be fine!

This will work for any program; e.g

env -u odd.variable myscript
1
  • 2
    If you want to replace your current shell, you'd use exec env ... bash. Without exec, you're creating a new child shell with a different environment, but the parent stays running. (Or just fix the docker environment to not run bash with weird env var names in the first place and restart everything, because the answer is basically that you can't change env vars with weird names from inside a bash process.) Apr 24, 2022 at 8:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .