Process substitution explained

Have you seen <( sub shell code ) in a shell script and wonder how it works?
It is called process substitution.
The shell substitutes it by a special file (device or fifo).
The ( sub shell code ) is run asynchronously in the background. Its output becomes the data of the special file.
You can see the special file names with e.g.

echo <( ls ) <( ls / )

and list their data with

cat <( ls ) <( ls / )

As usual you can redirect a file with <

tr '[:lower:]' '[:upper:]' < <( ls )

Note: there must be be a space between the < token and the <( token.
Note: the standard only allows one < redirection.

The ls runs asynchronously in the background (sub shell) while the tr runs in the foreground (main shell).
This is pretty much comparable with the pipe mechanism:

ls | tr '[:lower:]' '[:upper:]'

but in a standard shell the ls runs in the foreground and the tr runs asynchronously in the background.

Note: ksh and zsh run the last part of a pipe in the foreground!

That was all about process substitution as input.

There is a further usage for output:

ls > >( tr '[:lower:]' '[:upper:]' )

Yet it is rarely seen. It is pretty much the same as the "bread and butter" pipe

ls | tr '[:lower:]' '[:upper:]'

Arguments to commands are usually input files, not output files. And the output goes to stdout, so if you happen to see >( ) then certainly with a preceding > redirection.
Few commands like sort can directly create an output file.

sort -o >( tr '[:lower:]' '[:upper:]' ) /etc/group

Lesson learned:
process substitution for input is often useful.
process substitution for output is for geeks.

11 Likes

I don't know. Anybody who uses zenity will be aware of the message:

Gtk-Message:  GtkDialog mapped without a transient parent.       This is discouraged.

I found a remedy for this on StackExchange (sorry, I didn't keep the reference) which is basically

zenity .... 2> >(grep -v "GtkDialog mapped without a transient parent" >&2)

This will cull that message while allowing other error messages to pass through to the terminal.

Mind you, I've just checked and zenity 3.32.0 (Ubuntu 20.04) no longer emits that message.

Andrew

2 Likes

You are right, it allows straight post-processing of the stderr.
The alternative, nested redirection and pipe, looks weird:

{ zenity ... 2>&1 1>&3 | grep ... ; } 3>&1

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.