I am doing a major script re-write. Part of that is removing eval for the usual reasons one might avoid eval. I am running into trouble finding a viable way of managing the following scenario type.
Consider these two eval statements:
eval echo '${'#${role}'[@]}' users
loc_NagiosUsersAll+=($( eval echo '${'${role}'[@]}' " " ))
The first prints to screen the number of users within a given role. The second adds all of those users to a larger array.
Role is to be whatever the current role being assessed happens to be. Let's call it read_only. We could write that first statement as follows then:
printf "${#read_only[@]} users"
I have tried dozens of combinations of parentheses, quotation marks, and various acrobatics to ditch eval and get those to work.
Here is the echo echo version (using one of the actual roles) for comparison:
$ echo echo '${'#${role}'[@]}' users
echo ${#authorized_for_all_host_commands[@]} users
$ echo ${#authorized_for_all_host_commands[@]} users
6 users
$ eval echo '${'#${role}'[@]}' users
6 users
I've managed to ditch all the other eval statements but this type is dug in like a tick.
So, how can I do this more securely than using eval?
More code...
declare -a NagiosUserRolesAll=( authorized_for_read_only
authorized_for_all_services
authorized_for_all_hosts
authorized_for_system_information
authorized_for_configuration_information
authorized_for_system_commands
authorized_for_all_service_commands
authorized_for_all_host_commands )
function func_NagiosUserDataGet(){ # was load_data_tables
local -a loc_NagiosUsersAll=""
printf "Loading users into the different tables. \n"
for role in "${NagiosUserRolesAll[@]}"
do
declare -ag $role="($( cat ${svnFilePath} | sed -n "s/${role}=//p" | sed 's/,/ /g' ))"
declare -n ref="${role}" # copy the reference, not the contents of the array
printf "The role ${role} has ${#ref[@]} users. \n"
loc_NagiosUsersAll+=(${ref[@]})
loc_NagiosUsersAll+=" "
done
printf "Creating list of unique users. \n"
NagiosUsersAllClean=($( echo ${loc_NagiosUsersAll[@]} | tr ' ' '\n' |
sort -u ))
printf "Total users: ${#NagiosUsersAllClean[@]}. \n"
}
function func_NagiosUsersShow(){ # was show_all_users
if [[ "${svnFileExists}" == '1' ]] ; then
printf "You'll need to checkout a cgi.cfg file first. \n"
return 1
fi
printf "\nThese are the roles with their users. \n\n"
for role in "${NagiosUserRolesAll[@]}"
do
# declare -ng ref="${role}" # copy the reference, not the contents of the array
printf "These users are in ${const_TextRed}${role}"
printf "${const_TextPlain}: "
printf "${const_TextGreen}"
# printf "${ref[@]} \n" # FAILS
printf "${ref[*]} \n" # ALSO FAILS (prints one user for each role)
# eval echo '${'${role}'[@]}' # WORKS
printf "${const_TextPlain} \n"
done
printf "\nNow for a list of unique users. \n\n"
func_EnterToContinue
printf "Unique users list: \n"
for i in "${!NagiosUsersAllClean[@]}"
do
printf "$i: ${NagiosUsersAllClean[$i]} \n"
done
func_EnterToContinue
}
declare -n role="read_only".