6

Let's say I want to repeat the same string of environment variables before running various incantations of a command

if [[ some_thing ]]; then
    TZ=GMT LC_ALL=C LONG_ENV_VAR=foo my_command
elif [[ some_other_thing ]]; then
    TZ=GMT LC_ALL=C LONG_ENV_VAR=foo my_command --with-arg
else
    TZ=GMT LC_ALL=C LONG_ENV_VAR=foo my_command --with-other-arg
fi

Is there a way to combine those? Some options

  1. Set them via export

    export TZ=GMT
    export LC_ALL=C
    export LONG_ENV_VAR=foo
    if [[ ]] # ...
    

    This works but I would rather not have them continue to be set in the environment.

  2. Attempt to create a variable variable!

    local cmd_args="TZ=GMT LC_ALL=C LONG_ENV_VAR=foo"
    

    Unfortunately when I tried to run this via:

    $cmd_args my_command
    

    I got TZ=GMT: command not found.

  3. Just list them all out every time.

I also tried Googling for this, but "environment variable variable" isn't the easiest term to search for and I didn't get anywhere. Is there a fix for what I'm trying to do in #2? or am I stuck with some version of #1 and unsetting the vars afterwards?

  • Kevin, if any of the existing answers solve your problem, please consider accepting it by using the checkmark next to it. Thank you! – Jeff Schaller Apr 12 '17 at 1:33
12

I might use a subshell for this:

(
  export TZ=GMT LC_ALL=C LONG_ENV_VAR=foo
  if [[ some_thing ]]; then
    exec my_command
  …
  fi
)

That allows you to clearly set the variables once; have them present for anything you run inside the subshell, and also not be present in the main shell's environment.

12

There are various ways of doing this. Personally, I find functions clearer:

run_this(){
   TZ=GMT LC_ALL=C LONG_ENV_VAR=foo "$@"
}

if [[ some_thing ]]; then
    run_this my_command
elif [[ some_other_thing ]]; then
    run_this my_command --with-arg
else
    run_this my_command --with-other-arg
fi 
5

Point 2. is possible via env:

local env_args="greppable1=foo greppable2=bar"
env $env_args perl -E 'say for grep /greppable/, keys %ENV'

This may be complicated by bash word splitting rules if there's spaces in any of the env args, though.

  • 1
    You should clarify that the contents of $env_args have no effect in variable expansion in the command string itself: env A=B echo "$A" echos nothing (or echos what $A already contained). – alexis Dec 22 '15 at 22:30
  • @alexis - does A=B echo "$A" behave any differently for you? – mikeserv Dec 23 '15 at 8:05
  • It's the same (except that the env command allows pre-expansion of the variable definition string, which was what the OP needs). I should have included the env, but my point applies equally to both versions: any variables in the command itself will be expanded before the custom definitions take effect. The adjusted environment is only useful inside the program. On the other hand, A=B; echo "$A" (as two commands) will of course echo B. – alexis Dec 23 '15 at 8:28
0

this is what your arg array is for:

if    thing
then  set --
elif  something
then  set -- --with_arg
else  set -- --other_arg
fi&&  TZ=GMT LC_ALL=C LONG_ENV_VAR=foo my_command "$@"

Remember: an empty "$@" != "". It's just not there.

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.