-1

Comments show what errors I get when trying to define a function that loops through an array,

#!/usr/bin/bash

local to_be_bckd_p=("lightningd.sqlite3" "emergency.recover")
prefs=("aaa" "bbbb")
 
echo_array() {
  
  #for fl in "${1[@]}"; do echo "${fl}";done #${1[@]}: bad substitution
  #for fl in "${*[@]}"; do echo "${fl}";done #${@[@]}: bad substitution
  #for fl in "${@[@]}"; do echo "${fl}";done #${@[@]}: bad substitution
  for fl in "${to_be_bckd_p[@]}"; do echo "${fl}";done 
}

echo_fn() {
  echo "${1}" 
}

echo_array "${to_be_bckd_p[@]}"
echo_array "${prefs[@]}" #This loops through `"${to_be_bckd_p[@]}"`
echo_fn "Hi"

Using the keyword local in the function definition does not help. Why using ${1} doesn't work in defining a function that is meant to take an array as its argument whereas ${1} works fine in the definitions of simpler functions such as echo_fn?

John Smith
  • 835
  • 1
  • 7
  • 19
  • 1
    Your function is always looping through `${to_be_bckd_p[@]}` not its arguments. – Barmar Jun 12 '23 at 20:33
  • 1
    In the shell, arguments are always *strings*; they cannot be data structures like arrays. What you are doing currently is passing all of the elements of the array as arguments (each element as a separate argument). It's also possible to pass the array's *name* as an argument. But it is not possible to pass an array *as an array*. – Gordon Davisson Jun 12 '23 at 21:16
  • Does this answer your question? [How to iterate over an array using indirect reference?](https://stackoverflow.com/questions/11180714/how-to-iterate-over-an-array-using-indirect-reference) – pjh Jun 13 '23 at 00:15

2 Answers2

2

It seems you want to pass the values to the function, not the array. The values can be accessed as the elements of the $@ array:

#!/bin/bash
echo_array() {
    for fl in "$@" ; do
        echo "$fl"
    done 
}

echo_fn() {
    echo "$1" 
}

to_be_bckd_p=("lightningd.sqlite3" "emergency.recover")
prefs=("aaa" "bbbb")

echo_array "${to_be_bckd_p[@]}"
echo_array "${prefs[@]}"
echo_fn "Hi"
choroba
  • 231,213
  • 25
  • 204
  • 289
  • Why using `"$@[@]"` in the function definition doesn't work? I was using `[@]` both in the function definition as well as in the function call, following what I read in https://www.gnu.org/software/bash/manual/html_node/Arrays.html – John Smith Jun 14 '23 at 06:38
  • 1
    `$@` is a special array, its members are `$1`, `$2`, etc. You can't use the `[...]` syntax for it. – choroba Jun 14 '23 at 07:58
2

Assuming bash 4.2+, we can use a nameref to provide control of the array (eg, accessing array indices):

echo_array() {
  declare -n _arr="$1"                      # nameref

  for ndx in "${!_arr[@]}"                  # loop through array's indices
  do
      echo "$ndx : ${_arr[$ndx]}"           # print 'index : value'
  done
}

NOTE: for val in "${_arr[@]}" will loop through the array's values

Take for a test drive:

$ echo_array to_be_bckd_p                   # pass the name of the array
0 : lightningd.sqlite3
1 : emergency.recover

$ echo_array prefs                          # pass the name of the array
0 : aaa
1 : bbbb

$ declare -A assoc=( [a]=1 [b]=2 [c]=3 )    # add an associative array to the mix

$ echo_array assoc                          # pass the name of the array
a : 1
b : 2
c : 3
markp-fuso
  • 28,790
  • 4
  • 16
  • 36