Посмотрите справочную страницу для fork (2). Дочерний процесс наследует дескрипторы родительских файлов, включая стандартный ввод и стандартный вывод. Для одной команды оболочка просто позволяет дочернему процессу наследовать эти дескрипторы и записывать свои выходные данные в терминал. Для конвейера он разветвляет каждый процесс, устанавливает канал между выходом одного и входом следующего, а затем выполняет (exec (2)) каждый исполняемый файл дочернего процесса.