C'est parce que la version du tube crée un sous-shell, qui lit la variable dans son espace local qui est ensuite détruit lorsque le sous-shell se termine.
Exécutez cette commande
$ echo $$;cat | read a
10637
et utilisez pstree -p pour regarder les processus en cours d'exécution, vous verrez un shell supplémentaire suspendu à votre shell principal.
| |-bash(10637)-+-bash(10786)
| | `-cat(10785)