Pode haver uma maneira mais elegante de fazer o que você quer, mas isso funciona:
do
(cat /var/run/out& echo $! > cat_pid; wait) |
(nc -l 8080 <&0 & echo $! > nc_pid; wait) > >(
︙
(dividido em linhas separadas após o | para legibilidade).
Isso funciona envolvendo cada comando cujo PID você quer em um subshell,
rodando de forma assíncrona naquela sub-camada, capturando seu PID,
e então esperando o comando terminar.
(Isso, na verdade, coloca o comando de volta no primeiro plano.)
Use o truque Scott <&0
para obter um processo assíncrono em um script para ler sua entrada padrão correta.
Mas por que você está usando o “gato” ?
E por que você está usando > >(…) em vez de simples piping ?
Você pode simplificar isso um pouco:
while true
do
(nc -l 8080 < /var/run/out & echo $! > nc_pid; wait) |
while read line
do
do some stuff
done
done
deixando nc ler diretamente de /var/run/out ,
e usando um pipe simples em vez de substituição de processo.