Seu for
loop trata o $a
como uma string e não o executará.
Use $(command)
quando precisar executar algo dentro de outro comando.
Então, o que você faria no seu caso é (por favor, não faça isso, mas siga a dica abaixo):
for i in $($a); do echo hi $i; done
Dica adicional: Evite usar um loop for com a saída find, pois você terá problemas quando os nomes dos arquivos contiverem espaços.
No seu caso, o seguinte funcionará:
a="find . -type f"
while IFS= read -r i; do
echo "hi $i"
done < <($a)
<(command)
cria um arquivo temporário da saída do comando.