No seu exemplo, o loop while é executado em um subshell, portanto, as alterações na variável dentro do loop while não afetarão a variável externa. Isso é porque você está usando o loop com um pipe, o que automaticamente faz com que ele seja executado em um subshell.
Aqui está uma solução alternativa usando um loop while:
i=1
while read x; do
i=$(($i + 1))
echo $i
done <<<$(find tmp -type f)
echo $i
E aqui está a mesma abordagem usando um loop:
i=1
for x in $(find tmp -type f);
do
i=$(($i + 1))
echo $i
done
echo $i
Para mais informações, veja os seguintes posts:
Veja também o capítulo seguinte do Guia avançado de scripts do bash: