11

I'm trying to create an array of functions in order to iterate through each function in order.

declare -a FUNCTION
FUNCTION[1]="FUNCTION.A"
FUNCTION[2]="FUNCTION.B"
FUNCTION[3]="FUNCTION.C"

for i in "${!FUNCTION[@]}"; do
  ${FUNCTION[$i]};
done

This just prints out FUNCTION.A and says command not found. I need it to run the function. Suggestions?

1
  • 2
    This is because you didn't define function FUNCTION.A itself. :) Commented Jul 31, 2019 at 16:48

6 Answers 6

18

Works fine for me.

declare -a FUNCTION
FUNCTION[1]="FUNCTION.A"
FUNCTION[2]="FUNCTION.B"
FUNCTION[3]="FUNCTION.C"

#Define one of the functions
FUNCTION.A() { echo "Inside of FUNCTION.A"; }


$ for i in "${!FUNCTION[@]}"; do   ${FUNCTION[$i]}; done

OUTPUT:

Inside of FUNCTION.A
FUNCTION.B: command not found
FUNCTION.C: command not found
Sign up to request clarification or add additional context in comments.

Comments

4

Another way that I think looks a lot better

funcs_to_test=( voltage_force_landing voltage_warn_critical )

for testP in "${funcs_to_test[@]}"
do  
    $testP
done

And make sure to have written your functions above where you call this code

1 Comment

Unfortunately, this doesn't always call the respective functions, it only prints the function name. To call the function you should write ${funcs_to_test[testP]} instead of $testP.
3

It is possible to define functions from names kept in an array and then call these functions after their definition:

#!/bin/sh

declare -a functions=( a b c )
for f in ${functions[@]}; do
    eval "$f() { 
              echo "Hello from $f" 
              # ...
          }"
    $f
done

Alternatively:

#!/bin/sh

declare -a functions=( a b c )

a() { echo "Hello from $FUNCNAME"; }
b() { echo "Hello from $FUNCNAME"; }
c() { echo "Hello from $FUNCNAME"; }

for f in ${functions[@]}; do 
    $f
done 

Comments

1

I'm a moron........ The function must apparently be above where its being called. Kinda annoying. I wish all the functions could reside at the bottom.

Comments

1

You can also declare the function like this

FUNCTION=(FUNCTION.A FUNCTION.B FUNCTION.C)

And then iterate through it like this:

for i in "${!FUNCTION[@]}"; do
${FUNCTION[i]}

This should work. If you just call "$i" it will only print the functions name from the array.

Comments

0

To avoid that little nuisance, just put the body of the script into yet another function. (I usually call it "app_main", because "main" is the name of the script's function as far as bash is concerned.)

#!/usr/bin/env bash # more portable

first() { echo "${FUNCNAME[0]}: $@" ; }
second() { echo "${FUNCNAME[0]}: $@" ; }

app_main() { 
    first "hello"
    second "goodbye" 17 3.14159
}

app_main

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.