como exportar VARs de um subshell para um shell pai?

7

Eu tenho um script de shell Korn

#!/bin/ksh
# set the right ENV
case $INPUT in
abc)
  export BIN=${ABC_BIN}
  ;;
  def)
  export BIN=${DEF_BIN}
  ;;
  *)
  export BIN=${BASE_BIN}
  ;;
esac
# exit 0 <- bad idea for sourcing the file

agora esses VARs são exportados apenas em um subshell, mas eu quero que eles sejam configurados no meu shell pai também, então quando eu estiver no prompt, esses vars ainda estão definidos corretamente.

Eu sei sobre

. .myscript.sh

mas existe uma maneira de fazer isso sem 'sourcing'? como meus usuários muitas vezes esquecem de 'fonte'.

EDIT1: removendo a parte "exit 0" - isso foi apenas eu digitando sem pensar primeiro

EDIT2: para adicionar mais detalhes sobre por que eu preciso disso: meus desenvolvedores escrevem código para (para simplificar) 2 aplicativos: ABC & DEF. cada aplicativo é executado em produção por usrabc e usrdef de usuários separados, portanto, configure seus $ BIN, $ CFG, $ ORA_HOME, o que for - específico para seus aplicativos.

então

  • ABC's $ BIN = / opt / abc / bin # $ ABC_BIN no script acima
  • $ BIN do DEF = / opt / def / bin # $ DEF_BIN

etc.

agora, na caixa de desenvolvimento, desenvolvedores podem desenvolver ABC e DEF ao mesmo tempo sob sua própria conta de usuário 'justin_case', e eu faço com que eles acessem o arquivo (acima) para que eles possam alterar suas configurações de ENV var adiante. ($ BIN deve apontar para $ ABC_BIN de uma vez e então eu preciso mudar para $ BIN = $ DEF_BIN)

agora, o script também deve criar novos sandboxes para o desenvolvimento paralelo do mesmo aplicativo, etc. Isso faz com que eu faça isso interativamente, pedindo o nome do sandbox, etc.

  • / home / justin_case / sandbox_abc_beta2
  • / home / justin_case / sandbox_abc_r1
  • / home / justin_case / sandbox_def_r1

a outra opção que considerei é escrever aliases e adicioná-los ao perfil de todos os usuários

  • alias 'setup_env =. .myscript.sh '

e execute-o com

  • setup_env parameter1 ... parameterX

isso faz mais sentido para mim agora

    
por webwesen 08.07.2009 / 18:38

4 respostas

7

Eu acho que é um problema "não pode fazer" ...

Primeiro, você não deseja pesquisar esse script por causa da saída 0 no final.

Segundo, nenhum processo filho unix pode alterar diretamente o ambiente do pai. Caso contrário, todos os tipos de coisas malucas seriam possíveis.

Você poderia adicionar algo ao ambiente deles com o perfil padrão ou arquivos bashrc, ou você poderia escrever um wrapper para qualquer programa que eles estivessem tentando executar?

Permita-me elaborar sobre o conceito "wrapper".

Digamos que você queira executar o programa snoopy com PROD ou DEV na variável de ambiente "OPTIONS" dependendo se você deseja produção ou desenvolvimento. Se não estiver definido, digamos que o snoopy faz algo do tipo acabar com o banco de dados para produção e desenvolvimento ...

renomeie "snoopy" para snoopy.bin (ou .snoopy.bin)

coloque um script no mesmo local chamado "snoopy" que contenha isto:

#!/bin/sh

export OPTIONS

case "$OPTIONS" 
in
  PROD) ;;
  DEV) ;;
  *) OPTIONS=DEV ;;
esac

#the binary is actually named snoopy.bin 

exec "$0.bin" "$@"

Se você não quiser mexer no arquivo atual, coloque este script em algum lugar no sistema de arquivos que estará à frente do programa snoopy real no PATH do usuário e tenha um caminho completo para o binário na instrução exec do script. ..

    
por 08.07.2009 / 19:05
4

A resposta é sourcing. A terceirização permite incluir variáveis em um script no shell atual , mas nunca um pai disso. É verdade, você tem que ter cuidado para não usar nenhum comando de saída ou similar, porque isso fecharia seu shell atual.

Você pode criar um script usando o ".", por exemplo,

./myscript.ksh

    
por 09.07.2009 / 02:07
2

Talvez se você tentar ...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE='cat fifo'
rm fifo

Não é exatamente exportação variável, mas pode fornecer comunicação básica com o processo pai.

    
por 26.03.2012 / 06:10
1

OK, não ria agora. Solução muito rápida e muito suja é adicionar

echo "Please copy and paste this command:"
echo ""
echo "export BIN=\"$BIN\""

para o seu script.

Outra abordagem . Apenas exec um subordinado $ SHELL no seu script, talvez com um prompt diferente (altere $ PS1 para notificar os usuários sob qual ambiente eles estão trabalhando para reduzir a confusão).

Outra abordagem (minha favorita). Os usuários esquecem de criar seu script, por que isso? A terceirização é precisamente o caminho padrão a seguir. Talvez uma boa maneira de lembrá-los é remover a primeira linha ( #!/bin/sh ) e, em seguida, chmod a-x it. Ainda pode ser originado depois disso, mas obviamente não pode ser executado por engano.

Rant : No geral, sinto que você teve uma ideia estranha em primeiro lugar. Talvez não seja estranho ... Eu diria um pouco não-Unix em grande estilo. Eu nunca precisei exportar o ambiente para o pai em minha vida. Eu vi uma vez uma situação semelhante - login .profile perguntando qual dos três ambientes diferentes para definir para uma única conta oracle. Má idéia, no final, descobriu-se que os usuários preferiram migrar para sudo (eles sudo'd para três contas oraxxx diferentes). O que você está tentando alcançar, se posso perguntar?

    
por 08.07.2009 / 21:24