0

I don't know how else to word this so I'll do my best to explain. I have a function

main()
{

        if [[ "$1" = "-f" ]]
        then
                ($sendFirstEmail) "$1"

        elif [[ "$1" = "-s" ]]
        then
                ($sendSecondEmail) "$1"

        elif [[ "$1" = "-k" ]]
        then
                ($sendKillEmail) "$1"
        else
                echo "valid input not provided"
        fi
}

That I call like this main "$1" what I need to do is pass another argument into the other functions inside the main function that also takes the first argument passed to it. $sendFirstEmail etc. are the names of the other functions that also take the first argument passed to them. In essence this is how I want to call the script ./sendEmail.sh -f johndoe@mail.com Is this possible or is there a better way to achieve what I'm trying to do?

4
  • 2
    Why are the sendFirstEmail, sendSecondEmail, sendKillEmail variables inside subshells? Are those really variables or are they just functions? (Functions don't need to be called with $...in fact that can't be) – jesse_b Jun 21 '19 at 15:31
  • 1
    So the argument you pass into the sendemail functions is not the same argument that is being passed to main? Where does the second argument come from? – jesse_b Jun 21 '19 at 15:48
  • Possible duplicate of get first CLI argument after the options in shell scipt – oxr463 Jun 21 '19 at 15:51
  • Can you show where sentFirstEmail is defined. – ctrl-alt-delor Jun 21 '19 at 16:48
2

You can pass the position parameter(s) to them just like you have done with main however not outside the subshell.

main()
{
    if [[ "$1" == "-f" ]]
    then
        sendFirstEmail "$1"

    elif [[ "$1" == "-s" ]]
    then
        sendSecondEmail "$1"

    elif [[ "$1" == "-k" ]]
    then
        sendKillEmail "$1"
    else
        echo "valid input not provided"
    fi
}

I'm not sure what the purpose of the subshells were so I have removed them but if you do in fact need a subshell for some reason just put the parameter(s) inside it:

( sendFirstEmail "$1" )

As Kusalananda points out this particular example is better suited for a case construct rather than an if (see 3.2.4.2 Conditional Constructs)

main()
{
    case $1 in
        -f) sendFirstEmail "$1";;
        -s) sendSecondEmail "$1";;
        -k) sendKillEmail "$1";;
        *)  echo "valid input not provided" >&2;;
    esac
}

Or better yet, getopts

main()
{
    if getopts fsk opt; then
        case $opt in
            f)  sendFirstEmail "$1";;
            s)  sendSecondEmail "$1";;
            k)  sendKillEmail "$1";;
            *)  echo "valid input not provided" >&2;;
        esac
    fi
}

In the event you are actually trying to provide a second argument as Tim has suggested you could use the getopts optarg feature:

main()
{
    if getopts f:s:k: opt; then
        case $opt in
            f)  sendFirstEmail "$OPTARG";;
            s)  sendSecondEmail "$OPTARG";;
            k)  sendKillEmail "$OPTARG";;
            *)  echo "valid input not provided" >&2;;
        esac
    fi
}

In this case you would run main like:

main -f 'option to the -f argument'
10
  • 1
    case $1 ...; esac for less typing. – Kusalananda Jun 21 '19 at 15:40
  • I think this is what I'm looking for. It runs but it doesn't do anything. I want to run it as so sendEmail.sh -f johndoe@mail.com . – Michael Jun 21 '19 at 16:15
  • @Michael: Where does the johndoe@mail.com come from? Using my last example you would run your script with say: ./script.sh -f 'johndoe@mail.com' and then within the script you could call: main "$@" – jesse_b Jun 21 '19 at 16:16
  • Forgot to mention. The second argument is fed by a python script that just outputs an email address. So for the send*Email functions the first argument that gets passed to them is the email address. – Michael Jun 21 '19 at 16:19
  • So your python script is being run from within the bash script? – jesse_b Jun 21 '19 at 16:44
1

Could you just pass 2 arguments to your main function?

main()
{
    arg1=$1
    arg2=$2

    if [[ "$arg1" = "-f" ]]
    then
            ($sendFirstEmail "$arg2")

    elif [[ "$arg1" = "-s" ]]
    then
            ($sendSecondEmail "$arg2")

    elif [[ "$arg1" = "-k" ]]
    then
            ($sendKillEmail "$arg2")
    else
            echo "valid input not provided"
    fi
}

In this case, $arg2 in main() becomes $1 inside the various send*Email commands.

3
  • This did not work. Errors out command not found on the first line where the sendFirstEmail is called – Michael Jun 21 '19 at 16:20
  • you would have to have set up those variables to point to other functions or commands. sendKillEmail=/path/to/some/script, for example, for those to work. – Tim Kennedy Jun 21 '19 at 16:27
  • 2
    Are the $ (in sendFirstEmail etc ) there because you thought you needed them, remove the $. I think we are assuming that these are variables, but I am not so sure that we can make this assumption. – ctrl-alt-delor Jun 21 '19 at 16:47
0

At the risk of repeating what others have said: if, as you say, you are calling the script as (for example)  ./sendEmail.sh -f johndoe@mail.com, then you have to call

main "$1" "$2"
and change main() as follows:
main()
{
        if [[ "$1" = "-f" ]]
        then
                sendFirstEmail "$2"
 
        elif [[ "$1" = "-s" ]]
        then
                sendSecondEmail "$2"
 
        elif [[ "$1" = "-k" ]]
        then
                sendKillEmail "$2"
        else
                echo "valid input not provided"
        fi
}
so the second argument to the (outermost) script becomes the second argument to main(), and subsequently the (one and only) argument to the innermost functions.

I have changed $(function_name) to function_name because you said that $(function_name) didn’t work.

9
  • Still nothing. I think it's because the first argument technically needs passed twice. The first is the -f -s -k which then calls the right function, but that function also needs its first argument, not second argument. – Michael Jun 24 '19 at 17:16
  • What do you mean by “the first argument technically needs passed twice” and “that function also needs its first argument”? … … … … … … … … … … … … Are you saying that sendFirstEmail needs to be invoked as sendFirstEmail -f johndoe@mail.com and sendSecondEmail needs to be invoked as sendSecondEmail -s johndoe@mail.com? That would be inconsistent with your previous comment, “for the send*Email functions the first argument that gets passed to them is the email address.” Please try to explain what you need more clearly. – G-Man Says 'Reinstate Monica' Jun 24 '19 at 17:41
  • The first argument that gets passed to the sendEmail functions is the email address. The first argument that gets passed to the main script is the -f -s -k. There is no second argument, they both take the first arguments passed to them individually. – Michael Jun 24 '19 at 17:56
  • OK, that’s what I thought. But now please try to explain clearly why my answer is not working for you.  (Are you sure that you changed the line in the script that calls main from main "$1" to main "$1" "$2"?) – G-Man Says 'Reinstate Monica' Jun 24 '19 at 18:03
  • Yea I call the main function like that and then it errors out when the email gets passed to it. So it gets $1 and then the email would be $2 for the main function, right? But it errors out with a command not found on the email address. Also, if the inner functions aren't called like $function it won't even see that command as a function. – Michael Jun 24 '19 at 18:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.