Atribua múltiplas variáveis de ambiente a uma única variável e expanda-as no comando

6

Digamos que eu queira repetir a mesma sequência de variáveis de ambiente antes de executar vários encantamentos de um comando

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

Existe uma maneira de combinar isso? Algumas opções

  1. Defina-os via export

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

    Isso funciona, mas eu prefiro que eles não continuem sendo definidos no ambiente.

  2. Tentativa de criar uma variável variável!

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

    Infelizmente, quando tentei fazer isso via:

    $cmd_args my_command
    

    Eu tenho TZ=GMT: command not found .

  3. Basta listá-las todas as vezes.

Eu também tentei pesquisar isso, mas "variável de ambiente variável" não é o termo mais fácil de pesquisar e não cheguei a lugar nenhum. Existe uma solução para o que estou tentando fazer no segundo lugar? ou eu estou preso com alguma versão do # 1 e desarmando os vars depois?

    
por Kevin Burke 22.12.2015 / 19:59

4 respostas

12

Eu posso usar um subshell para isso:

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

Isso permite definir claramente as variáveis uma vez; tê-los presentes para qualquer coisa que você executar dentro do subshell, e também não estar presente no ambiente do shell principal.

    
por 22.12.2015 / 20:08
12

Existem várias maneiras de fazer isso. Pessoalmente, acho funções mais claras:

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 
    
por 22.12.2015 / 20:15
5

O ponto 2. é possível via env :

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

Isso pode ser complicado por regras bash de divisão de palavras, se houver espaços em qualquer um dos argumentos env, embora.

    
por 22.12.2015 / 20:18
0

é para isso que sua matriz arg é:

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 "$@"

Lembre-se: um vazio "$@" ! = "" . É só não existe .

    
por 23.12.2015 / 08:49