There are many similar questions, but I didn't understand any answer as solution of the following problem:
I want to create a bash function which holds two arguments, first is a variable name and second is a search string (for a file search).
As a result, I want the variable name holding an array of the found files.
I have a directory containing following files:
- a.jpg
- b.tif
- c.jpg
The function is defined as:
search-files--fill-array() { local variable_name="${1}" declare -a eval ${variable_name} local search_string="${2}" echo "${search_string}" local nullglob_setting=$(shopt -p nullglob) shopt -s nullglob found_files=(${search_string}) eval "${nullglob_setting}" eval ${variable_name}=(${found_files[@]}) }
but the last line results an syntax error. It should assign the array to the variable which was presented as first argument to the function, so the function is called:
search-files--fill-array my_variable_a "*.jpg"
So the desired result should be that
echo "${my_variable_a[@]}"
shows me the two files "a.jpg" and "c.jpg" as an array, i.e.
echo "${#my_variable_a[@]}"
shall result "2".
If it wouldn't have to be an array, the solution would be to use following last line:
eval ${variable_name}=\${found_files}
Without any success I also tried to use a while loop to form the new array from the old one, but this doesn't work too.
eval ${variable_name}="\${found_files[@]}"
produces that my_variable_a
holds a string but not an array.
Background
Perhaps my approach is completely wrong.
To make it clear: I want to have filled some variables each with an array which holds the filenames of files found by globbing (always the same way with different search “strings”). I expect only files, without any respect of subdirectories and I have to get sure, the results are always reliably sorted.)
And I want to avoid redundant code.
The shopt
part is necessary to assure, if no file exists in the current directory, the array is filled with zero entries, while without nullglob, there would be exact one entry with the content of the search “string“.
Solution
As Uncle Billy suggested, I can use declare -n var
here.
The working function:
search-files--fill-array() { declare -n function=$1 local shopt_setting=$BASHOPTS shopt -s nullglob function=($2) [[ :$shopt_setting: = *:nullglob:* ]] || shopt -u nullglob }
His proposed handling of resetting the nullglob
causes the function to not include any eval
anymore. You can read e.g. this stackexchange post to get to know, why avoiding eval
is worth considering.
nullglob
only in the function; see updated answer. Though you should be asking a different question about it.nullglob
handling, but you brought me into line. Thank you very much!