1

I have this contains function which is supposed to check if an array has a certain value. The array itself is passed as the 1st arg, and the value is the 2nd arg.

#!/usr/bin/env bash

set -e;

branch_type="${1:-feature}";
arr=( 'feature', 'bugfix', 'release' );

contains() {
    local array="$1"
    local seeking="$2"
    echo "seeking => $seeking";
#    for v in "${!array}"; do
     for v in "${array[@]}"; do
        echo "v is $v";
        if [ "$v" == "$seeking" ]; then
         echo "v is seeking";
            return 0;
        fi
    done
   echo "returning with 1";
   return 1;
}

if ! contains "$arr" "$branch_type"; then
    echo "Branch type needs to be either 'feature', 'bugfix' or 'release'."
    echo "The branch type you passed was: $branch_type"
    exit 1;
fi

echo "all goode. branch type is $branch_type";

if you run the script without any args, it should work, since the default is "feature", but for some reason, the search is not matching anything. I am not getting an error, but the contains functions is not working as desired.

When I run the script w/o any arguments, I get:

seeking => feature
v is feature,
returning with 1
Branch type needs to be either 'feature', 'bugfix' or 'release'.
The branch type you passed was: feature

now that's weird

2 Answers 2

1

NOTE: I'm going to show how to fix this so that it works in Bash 4.


I think you're passing the array into the function incorrectly:

$ cat contains.bash
#!/usr/bin/env bash

branch_type="${1:-feature}";
arr=('feature' 'bugfix' 'release');

contains() {
    local array=$1
    local seeking="$2"
    for v in ${!array}; do
        if [ "$v" == "$seeking" ]; then
            return 0;
        fi
    done
   return 1;
}

if ! contains arr $branch_type; then
    echo "Branch type needs to be either 'feature', 'bugfix' or 'release'."
    echo "The branch type you passed was: $branch_type"
    exit 1;
fi

echo "the array contains: $branch_type";

I changed things slightly and it now looks to be working:

$ ./contains.bash
the array contains: feature

Changes

I only made 2 modifications to your original script. I changed how the function contains() was being called so that it passes the bare name of the array arr for this line:

if ! contains arr $branch_type; then

and changed this line inside the function contains() where the array is set using the passed in arguments, taking the quotes off the setting of the local variable array:

    local array=$1

References

4
  • @AlexanderMills - sure thing, good luck w/ the rest of it.
    – slm
    Jul 7, 2018 at 7:45
  • yeah I found something that works with bash3, I think this only works with bash4...i have to support bash3, also I don't understand why you can do constains arr instead of contains "$arr" Jul 7, 2018 at 7:55
  • That's provided by Bash 4 now. The link I shared shows both 3 & 4 solutions.
    – slm
    Jul 7, 2018 at 7:56
  • got it yeah i added an answer with what seems to work Jul 7, 2018 at 7:59
1

Something idiomatic that works with Bash3, looks like this:

#!/usr/bin/env bash

set -e; 

branch_type="${1:-feature}";
arr=( 'feature' 'bugfix' 'release' );

contains() {

    local seeking="$1"
    shift 1;
    local arr=( "$@" )

    for v in "${arr[@]}"; do
        if [ "$v" == "$seeking" ]; then
            return 0;
        fi
    done
   return 1;
}

if ! contains "$branch_type" "${arr[@]}"; then
    echo "Branch type needs to be either 'feature', 'bugfix' or 'release'."
    echo "The branch type you passed was: $branch_type"
    exit 1;
fi

echo "the array contains: $branch_type";

the real hang up was I was trying to do this:

local seeking="$1"
local arr=( "$2" )

but this is necessary:

local seeking="$1"
shift 1;
local arr=( "$@" )
3
  • The arr array in the function is not needed: for v do if [ "$v" = "$seeking" ] ... done. This would loop over "$@".
    – Kusalananda
    Jul 7, 2018 at 9:04
  • oh thanks, so to be precise would it be for v; do? Jul 8, 2018 at 1:39
  • One out of for v do, for v; do or for v in "$@"; do.
    – Kusalananda
    Jul 8, 2018 at 6:26

You must log in to answer this question.

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