Para expandir a resposta aceita, para um entendimento geral, estou postando minha própria resposta.
Solução para o problema 1.
O primeiro problema é o uso de eval. eval é desnecessário aqui. É o suficiente para fazer uma substituição de comando usando $ (...)
find ./ -name '*.xml' | files=$(awk '{print $0}') ; echo $files
O segundo problema é o pipe. Como apontado por @cas - o pipe é executado em sua própria sub-rede. Portanto, o arquivo variável está vazio. Para resolver isso, remova awk e armazene o resultado de encontrar diretamente na variável.
files=$(find ./ -name '*.xml') ; echo "${files}"
Mas o comando acima não é uma matriz. Para torná-lo um array, use parênteses.
files=($(find ./ -name '*.xml')) ; echo "${files[0]}"
deve ser feito. Agora, o uso de aspas duplas na variável $ {files} é uma boa prática, porque, do contrário, espaços em nomes de arquivos criarão problemas. Além disso, a próxima boa prática seria usar o IFS. Isso garante que o shell não divida a palavra em espaços ou tabulações. IFS=$'\n'
seria dividido em novas linhas (saída de find) antes de armazenar o conteúdo na variável $ files.
IFS=$'\n' files=($(find ./ -name '*.xml')) ; echo "${files[0]}"
Então, o comando final para diferenciar os dois arquivos ou quaisquer dois arquivos é
files=($(find . -name '*.sh')) ; echo "${files[0]}" ; diff -y "${files[0]}" "${files[1]}"
Aqui 0 e 1 podem ser substituídos por qualquer um de um número válido na matriz ($ files).