syntax:expansion:proc_subst

This is an old revision of the document!


Process substitution

<( <LIST> )

>( <LIST> )

This only works on systems that support named pipes (FIFO - a special file) or the /dev/fd/NNNNN-syntax to access open files.

Process substitution is performed simultaneously with parameter expansion, command substitution and arithmetic expansion.

The command list <LIST> is executed and its

  • standard output filedescriptor in the <( … ) form or
  • standard input filedescriptor in the >( … ) form

is connected to a FIFO or a file in /dev/fd/. The filename (where the filedescriptor is connected) is then used as a substitution for the <(…)-construct.

That, for example, allows to give data to a command that can't be reached by pipelining (that doesn't expect its data from stdin but from a file).

If a process substitution is expanded as an argument to a function, or assigned to an environment variable when calling the function, the process substitution will be "held open" until the function returns.

This code is useless, but it demonstrates how it works:

$ echo <(ls)
/dev/fd/63

The output of the ls-program can be accessed by reading the file /dev/fd/63.

This is very useful in redirection statements. A wrong piece of code to count all files in /etc is:

counter=0

find /etc | while read; do
  ((counter++))
done

echo "$counter files"
Why this is wrong? Due to the pipe, the while read; do … done part is executed in a subshell. That also means counter is incremented in that subshell. When the pipeline finishes, the subshell is terminated, and the counter you access is the counter from the main shell - the one at "0"!

Process substitution helps us here to avoid the pipe (which is the reason for the subshell):

counter=0

while read; do
  ((counter++))
done < <(find /etc)

echo "$counter files"
This is the normal input file redirection < FILE, just that FILE is dynamically generated by process substitution:
< <(COMMAND)

This example demonstrates how process substitutions can be made to resemble "passable" objects. This results in converting the output of f's argument to uppercase.

f() {
    cat "$1" >"$x"
};

x=>(tr '[:lower:]' '[:upper:]') f <(echo 'hi there')

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
liungkejin, 2013/05/31 11:46, 2013/06/22 11:58

I found a fun thing:

(echo "YES")> >(read str; echo "1:${str}:first";)> >(read sstr; echo "2:$sstr:two")> >(read ssstr; echo "3:$ssstr:three")
gives
1:2:3:YES:three:two:first

You could leave a comment if you were logged in.
  • syntax/expansion/proc_subst.1340488524.txt
  • Last modified: 2012/06/23 21:55
  • by ormaaj