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 [email protected] 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, 2019 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, 2019 at 15:48
  • Possible duplicate of get first CLI argument after the options in shell scipt
    – oxr463
    Jun 21, 2019 at 15:51
  • Can you show where sentFirstEmail is defined. Jun 21, 2019 at 16:48

3 Answers 3

3

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, 2019 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 [email protected] .
    – Michael
    Jun 21, 2019 at 16:15
  • @Michael: Where does the [email protected] come from? Using my last example you would run your script with say: ./script.sh -f '[email protected]' and then within the script you could call: main "$@"
    – jesse_b
    Jun 21, 2019 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, 2019 at 16:19
  • So your python script is being run from within the bash script?
    – jesse_b
    Jun 21, 2019 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, 2019 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. Jun 21, 2019 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. Jun 21, 2019 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 [email protected], 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, 2019 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 [email protected] and sendSecondEmail needs to be invoked as sendSecondEmail -s [email protected]? 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. Jun 24, 2019 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, 2019 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"?) Jun 24, 2019 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, 2019 at 18:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .