Como você está iniciando esses processos em um subshell (por causa do pipe e por causa das opções (...) extras), o wait não sabe sobre nenhum filho que esperar. Você pode reescrever esse loop para que não exija um subshell como:
while read DIR; do
echo "reading..."
test -r "$DIR"/*_1.gz -a -r "$DIR"/*_2.gz || continue
pairedread $DIR &
done < <(find . -type d -print)
Espere apenas sobre filhos do processo atual. Quando você usa | , cria um subshell para as partes conectarem o stdin / stdout dos lados juntos. Qualquer processo lançado em um subshell não é um filho do processo "top", então wait não sabe sobre eles.
Portanto, neste caso, você foi frustrado ao lançar explicitamente sua pairedread em uma subshell com sintaxe () , e também por ter ocorrido dentro do bloco de um loop while em um pipeline.
Reescrevendo esse bloco para evitar o pipeline e removendo os subshells explícitos permite que o outer wait saiba sobre os processos filhos e faça o que você esperava