Existem muitas maneiras de fazer o que você está pedindo. Aqui está o meu rápido e sujo.
Como você já tem seus usuários em uma variável, você só precisa de um for loop para fazer sua formatação. Vou usar seus valores para o meu exemplo: T
userList="hiddenadmin fred joe kim"
echo "Please choose which user folder you would like to copy:"
count=0
for name in $userList;do
count=$((count+1))
printf '\t%s) %s\n' $count $name
echo
done
read -p "Choose from $(eval echo {1..$count}): " CHOICE
Esse loop irá ler seu userList , inicializar um contador e usar printf para a saída. O \t recuará suas seleções e \n enviará um CRLF.
Quando a opção de menu for impressa, o comando read solicitará a entrada do usuário e definirá sua seleção para a variável CHOICE . Você pode reutilizar a variável count na opção -p de read para exibir opções válidas. Você terá que adicionar algum código adicional para validar a entrada. Você pode fazer isso com uma simples declaração case .
case $choice in
1) #some code
;;
2) #some code
;;
*) echo "Invalid choice"
;;
esac