Problems setting or exporting variable when using multiple commands from same line.

I am experimenting with some scripting as a way to learn more about it. I have a simple script that calls two other scripts. Each script echos some stuff to prove it ran and then sets a simple variable and exports it.

I cannot get one of the variables to display back in the main calling script when I use a command form that sources the scripts from the same line:

. $MYROOT/junk && $MYROOT/morejunk

However, it works like this:

. $MYROOT/junk && . $MYROOT/morejunk

It also works like this:

. $MYROOT/junk && \
       . $MYROOT/morejunk

Maybe you must source each individual script. But, I used as a base for these experiments a shell that used this form, which does not source the individual commands:

   . $MYROOT/scripts/script1 && \
        $MYROOT/scripts/script2 && \
        [ -n "$MYDIR" ] && cd $MYDIR

and it works fine.

My version does execute but there are issues with the second variable I try to display. It seems to not be getting exported so that it can display properly.

Here are the three simple scripts followed by the output. Any insight would be appreciated. (BTW - I am not a programmer by trade but am rather trying to learn some stuff here.)

mytest script:

#!/bin/sh

if [ -z "$ZSH_NAME" ] && [ "x$0" = "x./my-test" ]; then
   echo "Error: This script needs to be sourced. Please run as '. ./my-test'"
else
   if [ -n "$BASH_SOURCE" ]; then
      MYROOT="`dirname $BASH_SOURCE`"
   else
      MYROOT="`pwd`"
   fi
   echo MYROOT = $MYROOT
   MYROOT=`readlink -f "$MYROOT"`
   echo MYROOT = $MYROOT
   export MYROOT

   . $MYROOT/junk && \
          $MYROOT/morejunk

   echo JUNK_VAR = $JUNK_VAR
   echo MOREJUNK_VAR = $MOREJUNK_VAR
   unset MYROOT
   unset JUNK_VAR
   unset MOREJUNK_VAR
fi


junk script

#!/bin/sh

echo "********************"
echo "* Executing junk   *"
echo "********************"

JUNK_VAR="junk_var"

export JUNK_VAR

morejunk script:

#!/bin/sh

echo "************************"
echo "* Executing morejunk   *"
echo "************************"

MOREJUNK_VAR="morejunk_var"

export MOREJUNK_VAR

Here is the output:

$ source my-test
MYROOT = .
MYROOT = /home/scottrif/test
********************
* Executing junk   *
********************
************************
* Executing morejunk   *
************************
JUNK_VAR = junk_var
MOREJUNK_VAR =
$

You must source them. Nothing else will work.

When you source it, it runs inside your current shell, exporting variables inside it for you to use.

When you run it directly, it executes in a new shell. Variables are set and exported in the new shell, which dies uselessly immediately thereafter, taking all its variables with it, because variables don't travel between parent and child. Children get copies of anything you've exported, but are independent thereafter.

Corona688,

Thanks very much for the explanation. This is subtle behaviour I of which I was not aware. I looked further into the scripts from which I based my test on that "seemed" to work and found that the second script (which was not sourced) does not do anything with variables that need to exist outside of the second temporary shell. That explains that!

Thanks again!