Isso deve fazer o que você quer:
$ ls > /dev/null & echo $!
Como você estava forçando o comando background em um subprocesso de várias maneiras, o primeiro shell não tinha nenhum processo em segundo plano e, portanto, $!
não foi atualizado.
Agora, o processo de segundo plano é iniciado pelo mesmo shell que executa echo $!
, então agora ele faz o que você quer.