0

I have an situation where there are some number, approximately 10 - 30, of environmental variables which pertain to a specific application. Before reconfiguring and recompiling the application, I want to remove (i.e., unset) all relevant environment variables. The list is too annoying to type out explicitly, so I'd like some automation.

I've looked at Unset group of variables, but it seems to be not quite what I want.

I came up with the below command, which shows what I want to do in principle (unset all environmental variables with "G4" in the names—actually it's not quite perfect it will unset it if it has "G4" in the values too).

printenv |grep G4 |awk 'BEGIN{FS="=";}{system("unset "$1);}'

As I should have expected, this doesn't affect the parent shell, which is the behaviour I want. I have encountered this before, in those cases I've used 'source', but I can't quite see how to do that here. It does not work to put the above command in a shell script and then source that, it seems.

I know I can just find out what's setting those variables in the first place and remove it and open another shell but I don't consider that a solution (although it's probably what I'll do while this question is being answered). I also don't want to unset them one-by-one, that's annoying and it seems like that shouldn't be necessary.

2
  • the link you posted is for php, of course it's not what you want :) Commented Apr 7, 2019 at 18:01
  • Is G4 at the start of the name? This is much easier if so: unset "${G4@}" will do. Commented Dec 1, 2024 at 17:19

3 Answers 3

1

That's nearly right. What you need to do is to get those commands out into the parent shell, and the way to do that is with command substitution. First print out the names of the variables. Your awk command is one way to do that:

printenv |grep G4 |awk 'BEGIN{FS="=";}{print $1;}'

Then use command substitution to feed the output to the shell:

unset $(printenv |grep G4 |awk 'BEGIN{FS="=";}{print $1;}')

The $(...) gives the output of the command to the shell, exactly as if you had typed it. I say "almost" because the shell processes the output a little, for instance removing newlines. In this case that's fine, because the unset command can take the name of multiple variables to unset. In cases where it would be a problem, quote the output using double quotes: "$(....)". The link gives all the details.

Sign up to request clarification or add additional context in comments.

Comments

1

This seems to work:

unset `printenv |grep G4 |awk 'BEGIN{FS="=";}{printf("%s ",$1);}'`

And I guess it's related to the answer for: Unset group of variables

I just didn't realize it

1 Comment

No, the link you posted is not related at all: it's for php whereas the question is for the shell
-1
declare -a vars_to_unset=(blue green red)
unset ${vars_to_unset[@]}

Will unset $blue, $green and $red at once.

Extending to the variables containing G4:

declare -a arr=($(env | cut -d= -f1 | grep G4))
unset ${arr[@]}

5 Comments

${array[@]} acts exactly like ${array[*]} -- to get the extra safety from [@], you need to quote your expansion: "${array[@]}". (But then, array=( $(...) ) is itself unsafe, so one needs to start before that point to make this answer comply with good practices).
I'd also worry about how this is going to behave if you have a variable set with a value like evil_variable='fine'$'\n''G4 PATH=muahaha' -- the cut -d= -f1 will emit G4 PATH, the grep G4 will pass the line into its output, and then the unquoted expansion will split on spaces and make your unset apply to PATH.
Waht's funny is that the other answers (inlcuded the accepted one) have exactly the same flaw, yet they've been upvoted while mine has been downvoted.
Wasn't my downvote; talk to the anonymous masses. I don't consider a single answer here worth upvoting, but I haven't cast any downvote either.
I wasn't accusing you, just that some downvoted an answer with the same flaws as the one they (or someone else) has voted up for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.