command output redirection using '-< <( ... )'

I needed to extract a shasum. This works, but can anyone explain why?

sed 's/^.*= //' -< <(openssl dgst -sha256 filename)

I'm familiar with the $( ) construct, but can't find docs for <( ), coupled with -<, which I assume is redirecting to the sed STDIN.

I know there are easier ways, but this construct eludes me.


The

<(openssl dgst -sha256 filename)

construct is a process substitution. It creates a file (or FIFO) behind the scenes and passes its name back to the command sequence.

< 

is a regular file redirection, redirecting the contents of the behind-the-scenes file to stdin and

-

is a placeholder recognized by sed to indicate that its input is coming from stdin.

Since sed is perfectly capable of reading from files, the -< seems unnecessary in this context;

sed 's/^.*= //' <(openssl dgst -sha256 filename)

should work just as well.


The <( COMMAND ) Bash construct is called process substitution.

It evaluates the COMMAND inside and redirects its output to a FIFO, a named pipe that gets a virtual file descriptor inside /dev/fd assigned. It acts like a temporary file that contains the output of the evaluated command.


The < Bash construct is called input redirection.

It takes a file descriptor on the right side and redirects its content to the STDIN (standard input) of the command on the left side.


The - is not a Bash construct but an argument for sed that specifies its input file. The special value - means to read from STDIN (which is also sed's default, so it could be omitted).


sed 's/^.*= //' - < <(openssl dgst -sha256 filename)

This line first runs openssl dgst -sha256 filename and caches its output in a FIFO. The file descriptor representing this named pipe is treated as input file that gets redirected to the STDIN of sed 's/^.*= //' -. This sed command reads from STDIN and removes every character before a "=" symbol followed by a space.