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

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

  • @AlexanderMills - sure thing, good luck w/ the rest of it. – slm Jul 7 '18 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" – Alexander Mills Jul 7 '18 at 7:55
  • That's provided by Bash 4 now. The link I shared shows both 3 & 4 solutions. – slm Jul 7 '18 at 7:56
  • got it yeah i added an answer with what seems to work – Alexander Mills Jul 7 '18 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=( "$@" )
  • The arr array in the function is not needed: for v do if [ "$v" = "$seeking" ] ... done. This would loop over "$@". – Kusalananda Jul 7 '18 at 9:04
  • oh thanks, so to be precise would it be for v; do? – Alexander Mills Jul 8 '18 at 1:39
  • One out of for v do, for v; do or for v in "$@"; do. – Kusalananda Jul 8 '18 at 6:26

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.