Isso acontece porque o seu loop while
está sendo executado em uma subshell. Modificações variáveis no subshell não afetam o pai.
Evite o pipe e o uso inútil de cat
fazendo algum redirecionamento:
while read line
do
let len+=${#line}
echo $len
done < $1
Isso não requer um subshell, então as alterações em $len
ficarão visíveis no pai.