Essa é uma armadilha bem conhecida, devido a esse recurso :
Each command in a pipeline is executed as a separate process (i.e., in a subshell).
para que as variáveis modificadas sejam locais para o subshell e não sejam visíveis novamente no pai.
Para evitar isso, reformule seu código para evitar o pipeline, com uma substituição de processo:
for arg in "$@"
do
readlink -e "$arg" || (( ++r ))
done > >(sort -u)