1

Bash Manual says

Process substitution is supported on systems that support named pipes ( fifos) or the /dev/fd method of naming open files.

  1. Does it mean that process substition is implemented either in terms of named pipes, or in terms of a file under /dev/fd?
  2. How is process substitution implemented in Linux?

    Does the following example mean that process substitution in Linux is implemented in terms of a file under /dev/fd, instead of named pipes?

    $ echo <(cat)
    /dev/fd/63
    
  3. In command1 <(command2), are the two comands running at the same time, or one starts after the other finishes running?

    If process substitution is implemented in terms of named pipes, does that mean that the two commands in the example of process substitution are running at the same time? My guess is because pipes and named pipes are used for communication between concurrently running processes, and the commands in a pipeline are running at the same time.

    I have this question when trying to understand the part 2 in a reply https://unix.stackexchange.com/a/286556/674.

Thanks.

2
  1. From strace output of strace -v -f -s150 -o log bash -c 'echo <(cat)', on my system, /dev/fd is implemented as pipe. It creates pipe with 3, 4 fds then dups 3 to 63.
  2. /dev/fd is just a symlink to /proc/self/fd. My system lacks /dev/fd symlink and output is just /proc/self/fd/63. Bash just operates with pipes. In bash source code it's seems that it maybe emulated just like other bash'isms like /dev/tcp but I am not sure. I do not see these on busybox ash however.
  3. If I replace echo builtin with tty and do strace over whole bash, I do see that tty runs first, then cat gets executed with preloaded pipe fds.
1

1., 2.: Yes, process substitution is implemented in terms of named pipes (open source = you can read the source)

3.

If process substitution is implemented in terms of named pipes, does that mean that the two commands in the example of process substitution are running at the same time?

Yes, it does mean that they run concurrently.

1

For point 3, If we define:

$ d(){ printf '%7s %7s %s\n' "$BASHPID" "$1" $(date -u +'%H:%M:%S'); }
$ p1(){ d START; readarray -t a; printf '%s\n' "${a[@]}" ; sleep 2; d END; }
$ p2(){ d START; sleep 2; d END; }

Then, this:

$ p1 < <(p2)

Will print:

   8517   START 20:31:38
  11764   START 20:31:38
  11764     END 20:31:40
   8517     END 20:31:42

That means that both start together, but p1 has to wait for p2 to end to close the read, then it sleep and ends.

In short: They run concurrently.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.