0

I'm trying to figure out how to pass an argument with a function call from one function to another in the same bash script. Here's what I've got so far:

#!/usr/bin/env bash
# File: nevens.sh

function isiteven {
    if (( "$element%2"=="0" ))
    then
        echo 1
    fi
}

function nevens {
    local result=0
    for element in $@
    do
        if (( $(isiteven) == 1 ))    # $(isiteven "$element")
        then
           result=$result+1
        fi
    done

    echo $result
}

I've tried calling $(isiteven) and hard-coding $element in front of %2==0 inside the isiteven function. And I've tried passing the argument with the function call, either $(isiteven $element) or $(isiteven "$element"), but then I'm not sure what I should code in front of %2==0 to do the math.

I'm using Ubuntu 18.04 on a dedicated machine.

8
  • 1
    BTW, if you defined isiteven() { (( ( $1 % 2 ) == 0 )); }, then you could just write if isiteven "$element"; then. That works because the default return value of a function is $?, and if branches on return value. This is far more efficient than making your function write to stdout, and then needing to capture that stdout through use of a subshell (thus requiring FIFO setup and a fork to create the subshell). Commented Sep 19, 2018 at 3:20
  • 1
    ...see this code running at ideone.com/mQgodw Commented Sep 19, 2018 at 3:23
  • @CharlesDuffy You could even use isiteven() (( $1%2 == 0 )). Commented Sep 19, 2018 at 5:11
  • 1
    @KarlBaker It's because the function body is a compound command, which includes conditional constructs (see this article). While a neat tidbit to know, I'd argue that using it in any environment where anybody other than you will ever look at your shell code is not advisable, as the vast majority of people will be confused, and it really only saves a few keystrokes. Commented Sep 19, 2018 at 11:15
  • 1
    @KarlBaker Yes, your description above is accurate. (There are some minor quibbles to be had -- strictly, $? is a special parameter, not a variable -- but all the important aspects of your description were spot on). One bit of magic involved: For UNIX exit codes (as stored in $?), 0 is true and all other numbers are false (which is why exit 1 or return 1 is used for errors in scripts), but in an arithmetic context 0 is false and all positive integers are true. This gets fixed up in how (( )) translates its numeric results to UNIX exit codes: (( 1 )) sets $? to 0, and the inverse. Commented Sep 19, 2018 at 13:14

1 Answer 1

2

Just like you do for a scripts.

# Just an example to indicate to how to pass arguments.
isiteven() {
    echo "Command line arguments: $@"
}

nevens() {
    declare result=0
    declare element
    for element in "$@"; do
       # Do necessary logic here. 
       isiteven "$element"
    done
}
Sign up to request clarification or add additional context in comments.

6 Comments

Consider POSIX rather than ksh function syntax: isiteven() { instead of function isiteven { will be more portable across POSIX-family shells.
BTW, result=$result+1 would change result=1 to result=1+1. Maybe you mean result=$((result+1)), to change it to result=2?
I was just addressing his/her main issue of passing argument rather than looking at his logic. You are right. Will fix it now.
Thanks, @CharlesDuffy, that fixed my second (unstated) issue on the incrementer. And your advice on the POSIX syntax for declaring functions is helpful as I had read it was merely a matter of personal preference.
@VivekAkupatni, thanks, my script works with if isiteven "$element".
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.