How to export VARs from a subshell to a parent shell

environment-variablesshellunix

I have a Korn shell script

#!/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

now these VARs are export'ed only in a subshell, but I want them to be set in my parent shell as well, so when I am at the prompt those vars are still set correctly.

I know about

. .myscript.sh

but is there a way to do it without 'sourcing'?
as my users often forget to 'source'.


EDIT1: removing the "exit 0" part – this was just me typing without thinking first

EDIT2: to add more detail on why do i need this: my developers write code for (for simplicity sake) 2 apps : ABC & DEF. every app is run in production by separate users usrabc and usrdef, hence have setup their $BIN, $CFG, $ORA_HOME, whatever – specific to their apps.

so

  • ABC's $BIN = /opt/abc/bin # $ABC_BIN in the above script
  • DEF's $BIN = /opt/def/bin # $DEF_BIN

etc.

now, on the dev box developers can develop both ABC and DEF at the same time under their own user account 'justin_case', and I make them source the file (above) so that they can switch their ENV var settings back and forth. ($BIN should point to $ABC_BIN at one time and then I need to switch to $BIN=$DEF_BIN)

now, the script should also create new sandboxes for parallel development of the same app, etc. this makes me to do it interactively, asking for sandbox name, etc.

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

the other option i have considered is writing aliases and add them to every users' profile

  • alias 'setup_env=. .myscript.sh'

and run it with

  • setup_env parameter1 … parameterX

this makes more sense to me now

Best Answer

I think it is a "no can do" sort of problem...

First -- you wouldn't want to source that script because of the exit 0 at the end.

Second, no unix child process can directly change the environment of the parent. Otherwise all sorts of crazy things would be possible.

Could you add something to their environment with the default profile or bashrc files, or could you write a wrapper for whatever program it is they are trying to run?

Allow me to elaborate on the "wrapper" concept.

Let's say you want to run the program snoopy with either PROD or DEV in environment variable "OPTIONS" depending on if you want production or development. IF it isn't set, let's say snoopy does something zany like wipe out the database for production and development...

rename "snoopy" to snoopy.bin (or .snoopy.bin)

then put a script in that same location named "snoopy" that contains this:

#!/bin/sh

export OPTIONS

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

#the binary is actually named snoopy.bin 

exec "$0.bin" "$@"

If you don't want to muck with the actual file, put this script somewhere in the filesystem that will be ahead of the actual snoopy program in the user's PATH and have a full path to the binary in the script's exec statement...