como exportar VARs de um subshell para um shell pai?

como exportar VARs de um subshell para um shell pai?

Eu tenho um script Korn Shell

#!/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 quero que eles sejam definidos em meu shell pai também, portanto, quando chegar o prompt, esses vars ainda estarão configurados corretamente.

Eu sei sobre

. .myscript.sh

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


EDIT1: removendo a parte "exit 0" - fui só eu digitando sem pensar primeiro

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

então

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

etc.

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

agora, o script também deve criar novos sandboxes para desenvolvimento paralelo do mesmo aplicativo, etc. isso me faz fazer isso de forma interativa, 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=. .meuscript.sh'

e executá-lo com

  • setup_env parâmetro1 ... parâmetroX

isso faz mais sentido para mim agora

Responder1

Eu acho que é um problema do tipo "não posso fazer" ...

Primeiro - você não gostaria de obter 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, todo tipo de loucura seria possível.

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

Permita-me elaborar o conceito de "invólucro".

Digamos que você queira executar o programa snoopy com PROD ou DEV na variável de ambiente "OPTIONS", dependendo se deseja produção ou desenvolvimento. SE não estiver definido, digamos que o Snoopy faça algo maluco, como destruir o banco de dados para produção e desenvolvimento...

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

em seguida, 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 real, coloque este script em algum lugar do 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...

Responder2

A resposta é terceirização. O Sourcing permite incluir variáveis ​​em um script noatualshell, mas nunca um pai disso. É verdade, você deve ter cuidado para não usar nenhum comando de saída ou similar, pois isso fecharia seu shell atual.

Você pode criar um script usando o ".", ou seja

. ./meuscript.ksh

Responder3

Talvez se você tentar...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

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

Responder4

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

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

ao seu roteiro.

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

Outra abordagem(meu favorito). Os usuários esquecem de fornecer seu script, por que isso? A terceirização é precisamente o caminho padrão a seguir. Talvez uma boa maneira de lembrá-los seja remover a primeira linha ( #!/bin/sh) e depois chmod a-xela. Ele ainda pode ser obtido depois disso, mas obviamente não pode ser executado por engano.

Desabafo: Resumindo, sinto que você teve uma ideia estranha em primeiro lugar. Talvez não seja estranho... eu diria um estilo um tanto não-Unix. Nunca precisei exportar ambiente para os pais em minha vida. Certa vez, vi uma situação semelhante - login .profile perguntando qual dos três ambientes diferentes definir para uma única conta Oracle. Má ideia, no final descobriu-se que os usuários preferiram migrar para o sudo (eles fizeram o sudo para três contas oraxxx diferentes). O que você está tentando alcançar, se posso perguntar?

informação relacionada