bash can a sourced script tell if a getops has been passed to parent

361 views Asked by At

I am wondering if & how a sourced bash script can tell if a getops variable was passed to a parent, such as,

.parent.sh -a MyVarForChild_a

in the parent.sh I call . child.sh and I would like to check if the -a MyVar was passed. I would prefer NOT to use the getops var in the parent and set the var if possible, rather use something similar to getops in the child to test if that var was passed, then set it.

parent.sh

#!/bin/sh
set -x

#confirm bash or dash (ec2)
echo $SHELL

child_a="/home/userX/child_a.sh"
. ${child_a} "$@" -b TestVar

child_a.sh

#!/bin/sh
set -x

while getopts "a:b:" OPTION
do
     case $OPTION in
        a)
            MyPassedVar=$OPTARG 
            ;;
        b)
            MyTestVar=$OPTARG 
            ;;     
       esac
done

echo $MyPassedVar
echo $MyTestVar

thx, Art

UPDATED for feedback as below answers....

The below answer from @Robin Hsu works for the above code and is a valid answer for the question asked and outputs

$ /home/userX/parent.sh -a ThisIsPassed
+ echo /bin/bash
/bin/bash
+ child_a=/home/userX/child_a.sh
+ . /home/userX/child_a.sh -a ThisIsPassed -b TestVar
++ set -x
++ getopts a:b: OPTION
++ case $OPTION in
++ MyPassedVar=ThisIsPassed
++ getopts a:b: OPTION
++ case $OPTION in
++ MyTestVar=TestVar
++ getopts a:b: OPTION
++ echo ThisIsPassed
ThisIsPassed
++ echo TestVar
TestVar

However it seems getops will only be executed once per parent & child, so adding getops in the parent will stop it working in the child, such as

parent.sh (ver2)

#!/bin/sh

set -x
#confirm bash or dash (ec2)
echo $SHELL

while getopts "x:" OPTION
do
     case $OPTION in
        x)
            MyXvar_notPassed=$OPTARG 
            ;;
       esac
done

child_a="/home/userX/child_a.sh"
. ${child_a} "$@" -b TestVar

outputs

$ /home/userX/parent.sh -a ThisIsPassed
+ echo /bin/bash
/bin/bash
+ getopts x: OPTION
/home/userX/parent.sh: illegal option -- a
+ case $OPTION in
+ getopts x: OPTION
+ child_A=/home/userX/child_a.sh
+ . /home/userX/child_a.sh -a ThisIsPassed -b TestVar
++ set -x
++ getopts a:b: OPTION
++ echo

++ echo

additionally if I add a 2nd child script, the 2nd child (child_b) fails the getops,

parent.sh

#!/bin/sh
set -x

#confirm bash or dash (ec2)
echo $SHELL

child_a="/home/userX/child_a.sh"
. ${child_a} "$@" -b TestVar

child_b="/home/userX/child_b.sh"
. ${child_a} "$@" -z OtherVar

child_a.sh

#!/bin/sh
set -x

while getopts "a:b:" OPTION
do
     case $OPTION in
        a)
            MyPassedVar=$OPTARG 
            ;;
        b)
            MyTestVar=$OPTARG 
            ;;     
       esac
done

echo $MyPassedVar
echo $MyTestVar

child_b.sh

#!/bin/sh
set -x

while getopts "a:z:" OPTION
do
     case $OPTION in
        a)
            MyPassedVarA=$OPTARG 
            ;;
        z)
            MyOtherVar=$OPTARG 
            ;;     
       esac
done

echo $MyPassedVarA
echo $MyOtherVar

outputting

$ /home/userX/parent.sh -a ThisIsPassed
+ echo /bin/bash
/bin/bash
+ child_a=/home/userX/child_a.sh
+ . /home/userX/child_a.sh -a ThisIsPassed -b TestVar
++ set -x
++ getopts a:b: OPTION
++ case $OPTION in
++ MyPassedVar=ThisIsPassed
++ getopts a:b: OPTION
++ case $OPTION in
++ MyTestVar=TestVar
++ getopts a:b: OPTION
++ echo ThisIsPassed
ThisIsPassed
++ echo TestVar
TestVar
+ child_b=/home/userX/child_b.sh
+ . /home/userX/child_b.sh -a ThisIsPassed -z OtherVar
++ set -x
++ getopts a:z: OPTION
++ echo

++ echo

Supplemental question

How can I have a parent + children with each child having a getops?

thx Art

1

There are 1 answers

4
Robin Hsu On BEST ANSWER

. child.sh has its own argument list. This means it is legal for child.sh to receive arguments in command line like this:

. child.sh arg1 arg2 arg3

So, I think if you want to pass the vars, you need to do this:

. child.sh "$@"

--Update-- To your further question, you should write your script mimic to the one you wrote, for the getopts part, like this:

while getopts "a:b:" OPTION
do
     case $OPTION in
       a)
            MyPassedVar=$OPTARG 
            ;;
       b)
            MyOptionB=$OPTARG
            ;;
       esac
done

echo $MyPassedVar
echo $MyOptionB

--update-- try

.  ./child.sh "$@"

It seems that bash can accept child.sh (if your parent script starts with #!/bin/bash), but sh can only accept ./child.sh