¿Cómo exportar VAR de un subshell a un shell principal?

10

Tengo un 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

ahora estos VAR se exportan solo en un subshell, pero quiero que se establezcan también en mi shell principal, por lo que cuando estoy en el indicador, esos vars todavía están configurados correctamente.

Se acerca de

. .myscript.sh

pero ¿hay alguna manera de hacerlo sin 'abastecimiento'? como mis usuarios a menudo se olvidan de 'fuente'.


EDITAR1: eliminando la parte "salir 0" - esto fue solo yo escribiendo sin pensar primero

EDIT2: para agregar más detalles sobre por qué necesito esto: mis desarrolladores escriben código para (por simplicidad) 2 aplicaciones: ABC y DEF. cada aplicación se ejecuta en producción por usuarios separados usrabc y usrdef, por lo tanto, han configurado sus $ BIN, $ CFG, $ ORA_HOME, lo que sea, específico para sus aplicaciones.

entonces

  • $ BIN de ABC = / opt / abc / bin # $ ABC_BIN en el script anterior
  • $ BIN de DEF = / opt / def / bin # $ DEF_BIN

etc.

ahora, en el cuadro de desarrollo, los desarrolladores pueden desarrollar tanto ABC como DEF al mismo tiempo bajo su propia cuenta de usuario 'justin_case', y hago que obtengan el archivo (arriba) para que puedan cambiar sus configuraciones de ENV var. ($ BIN debe apuntar a $ ABC_BIN a la vez y luego necesito cambiar a $ BIN = $ DEF_BIN)

ahora, el script también debería crear nuevos sandboxes para el desarrollo paralelo de la misma aplicación, etc., esto me hace hacerlo interactivamente, pidiendo el nombre del sandbox, etc.

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

la otra opción que he considerado es escribir alias y agregarlos al perfil de cada usuario

  • alias 'setup_env =. .myscript.sh '

y ejecutarlo con

  • setup_env parámetro1 ... parámetroX

esto tiene más sentido para mí ahora

webwesen
fuente
Sí, puede hacerlo con un alias o función (prefiero las funciones yo mismo) donde tiene la función prod () {export VAR = snoopy; }; y la función dev () {export VAR = woodstock; };
chris

Respuestas:

11

Creo que es un problema de "no puedo hacer" ...

Primero: no querrás obtener ese script debido a la salida 0 al final.

En segundo lugar, ningún proceso hijo de Unix puede cambiar directamente el entorno del padre. De lo contrario, todo tipo de locuras serían posibles.

¿Podría agregar algo a su entorno con el perfil predeterminado o los archivos bashrc, o podría escribir un contenedor para cualquier programa que intenten ejecutar?

Permítanme elaborar el concepto de "envoltura".

Supongamos que desea ejecutar el programa snoopy con PROD o DEV en la variable de entorno "OPCIONES" dependiendo de si desea producción o desarrollo. SI no está configurado, digamos que snoopy hace algo estrafalario como borrar la base de datos para producción y desarrollo ...

cambie el nombre de "snoopy" a snoopy.bin (o .snoopy.bin)

luego coloque un script en esa misma ubicación llamada "snoopy" que contenga esto:

#!/bin/sh

export OPTIONS

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

#the binary is actually named snoopy.bin 

exec "$0.bin" "$@"

Si no desea manipular el archivo real, coloque este script en algún lugar del sistema de archivos que esté por delante del programa de snoopy real en la RUTA del usuario y tenga una ruta completa al binario en la declaración ejecutiva del script ...

Chris
fuente
5

La respuesta es el abastecimiento. El aprovisionamiento le permite incluir variables en un script en el shell actual , pero nunca un padre de eso. Es cierto, debe tener cuidado de no usar ningún comando de salida o similar, ya que eso cerraría su shell actual.

Puede obtener un script utilizando el ".", Es decir

. ./myscript.ksh

txwikinger
fuente
3

Quizás si lo intentas ...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

No es exactamente una exportación variable, pero puede proporcionar una comunicación básica con el proceso padre.

Oscar
fuente
1

OK, no te rías ahora. Solución muy rápida y muy sucia es agregar

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

a tu guión.

Otro enfoque . Solo execun $ SHELL subordinado en su script, tal vez con un aviso diferente (cambie $ PS1 para notificar a los usuarios en qué entorno están trabajando para reducir la confusión).

Otro enfoque (mi favorito). Los usuarios se olvidan de buscar su script, ¿por qué? El aprovisionamiento es precisamente el camino a seguir estándar. Tal vez una buena forma de recordarles es eliminar la primera línea ( #!/bin/sh) y luego chmod a-x. Todavía puede obtenerse después de eso, pero obviamente no puede ejecutarse por error.

Rant : En general, siento que has tenido una idea extraña en primer lugar. Tal vez no sea extraño ... Diría que no es un estilo de Unix. Nunca en mi vida he necesitado exportar ambiente a padres. Una vez vi una situación similar: iniciar sesión .profile preguntando cuál de los tres entornos diferentes establecer para una sola cuenta de Oracle. Mala idea, al final resultó que los usuarios preferían migrar a sudo (sudo'd a tres cuentas oraxxx diferentes). ¿Qué estás tratando de lograr, si puedo preguntar?

kubanczyk
fuente