【发布时间】:2018-05-09 09:26:37
【问题描述】:
我正在重写一个主要的脚本。其中一部分是出于通常可能避免 eval 的原因而删除 eval。我在寻找管理以下场景类型的可行方法时遇到了麻烦。
考虑这两个 eval 语句:
eval echo '${'#${role}'[@]}' users
loc_NagiosUsersAll+=($( eval echo '${'${role}'[@]}' " " ))
第一个打印以筛选给定角色内的用户数量。第二个将所有这些用户添加到一个更大的数组中。
角色是被评估的当前角色恰好是任何角色。我们称它为只读。我们可以将第一个语句写成如下:
printf "${#read_only[@]} users"
我已经尝试了几十种括号、引号和各种杂技的组合来放弃 eval 并让它们发挥作用。
这里是 echo echo 版本(使用实际角色之一)进行比较:
$ 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
我已经设法放弃了所有其他 eval 语句,但这种类型就像一个勾号一样被挖掘出来。
那么,我怎样才能比使用 eval 更安全?
更多代码...
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
}
【问题讨论】:
-
如果你的 bash 版本是 4.3 或更高版本,你可以说类似
declare -n role="read_only"。 -
这将如何帮助解决此声明的问题?评估 echo '${'#${role}'[@]}' 用户
-
我已经发布了下面的示例代码。
标签: arrays bash command eval substitution