For <( ... ): 1. parent: pipe2([3, 4]) 2. parent: dup2(3, 63) 3. parent: close(3) 4. parent: fork() 4. child: dup2(4, 1) # now STDOUT is the writing end 5. child: proceed to ... 6. parent: close(4) 7. parent: openat("/dev/fd/63", O_RDONLY) and expand as "/dev/fd/63" For >(...): Much the same but read/write fd's are inverted and #7 opens with O_WRONLY.