É possível declarar uma variável local sem sobrescrever o original para os processos filhos?

1

Se eu tiver uma variável ENV pré-existente, é possível declarar uma nova variável local com o processo filho usando o valor original?

Tenha em mente que não sei quais variáveis o processo filho usará. Então, salvar o valor do original e fazer var=original mycmd -with -args não será suficiente.

# print.sh:
echo "from print.sh: $MY_VAR"

# local.sh:
run () {
  declare MY_VAR="should not be seen"
  bash print.sh
}
MY_VAR="original" run

As impressões acima: from print.sh: should not be seen em vez de: from print.sh: original , mesmo se eu usar local , declare etc. na function body

Eu esperava que declare/local/typeset tivesse algumas opções, mas não encontrei nenhuma que diga: defina um valor para essa variável localmente, mas os processos filhos usam o original.

    
por dgo.a 28.03.2016 / 02:46

2 respostas

0

Uma convenção comum é usar todas as maiúsculas para variáveis de ambiente e todas as minúsculas para variáveis locais de script. Desta forma, uma variável local nunca colide com uma variável de ambiente.

Eu não acho que o zsh tenha uma opção para distinguir entre o valor local e o valor exportado de uma variável. Uma solução alternativa é salvar e restaurar o valor. Isso significa listar as variáveis que você deseja salvar.

run () {
  typeset -A _saved_variables
  _saved_variables[foo]=$foo _saved_variables[bar]=$bar
  local foo='not seen' bar='not seen either'
  …
  foo=$_saved_variables[foo] bar=$_saved_variables[bar] bash print.sh
}

Se você quiser preservar todo o ambiente, poderá executar typeset -px para imprimi-lo de forma analisável. Observe que isso não funcionará se você tiver exportado variáveis somente leitura; Para lidar com esse caso, você precisaria passar pelos nomes das variáveis e selecionar apenas os que não são somente leitura.

run () {
  _saved_variables='typeset -px'
  local foo='not seen' bar='not seen either'
  …
  (eval $_saved_variables; exec bash print.sh)
}

Outra opção é estruturar seu script de maneira diferente. Determine o comando que você deseja executar em um subshell e imprima-o (adequadamente citado) para o pai executar.

run () {
  # you can clobber variables here
  …
  printf %q "bash print.sh"
}
eval $(run)
    
por 29.03.2016 / 01:38
0

A questão é voltada para Zsh. Mas, para os usuários do Bash e do mksh, é possível ter ressalvas: link

    
por 13.04.2017 / 14:36