Вы должны попробовать запустить strace снова с флагом -f, чтобы он следовал за вилками. На данный момент вы можете видеть только то, что делает ваш процесс верхнего уровня, вы не можете видеть, что делают ваши дочерние процессы.
Процесс верхнего уровня создает две трубы. Трубы используются программами для общения друг с другом. Первый канал имеет конец чтения на fd 3 и конец записи на fd 4. Второй канал имеет конец чтения на fd 5 и конец записи на fd 6.
Поскольку программа верхнего уровня закрывает все четыре fds после вызова двух дочерних программ, похоже, что они просто используются внутренне дочерними программами (которые обе получают копии fds). Это необычно, потому что обычно я ожидаю увидеть, как родительский процесс будет держать один открытый, чтобы общаться с ребенком. Похоже, что в вашей трассировке отсутствует важная информация о том, что происходило с fds после каждого форка.
Это то, что я ожидал бы увидеть, если бы процесс открывал каналы для того, чтобы захватить stdout от потомка, например:
parent_pid: pipe[3,4]
parent_pid: clone() = child_pid
parent_pid: close(4)
child_pid: dup(4,1)
child_pid: close(4)
child_pid: close(3)
child_pid: execve(some program)
child_pid: write(1)
parent_pid: read(3)
parent_pid: wait(child_pid)
child_pid: exit()