if [ -z "$OPTION" ] # if option is not given(empty) then:
        command1 --defaultOption
        command1 $OPTION
fi \
  2> >( function1 "$DETAILS" ) \
  < <( command2 "$OTHER_DETAILS" )

I am seriosly puzzled how directing stderr to a file and feeding a file into stdin interact with an if statement. Well known things are: 2>filename# Redirect stderr to file "filename." 2>>filename# Redirect and append stderr to file "filename." command < input-file > output-file < input-file command > output-file

My guess would be:

command2 generates a file which is forwarded either to command1's stdin with --defaultOption (if $OPTION is empty, then case) or to command1's stdin with $OPTION (if $OPTION is not empty, else case). stderr of command1 is redirected to function1 (which as an example might be some sort of progress-bar display).

So my questions are:

Are the whitespaces between the brackets < < and > > necessary? Is it actual an append (whitespace ignored), or a "double" redirect? Am I missing an interaction between brackets and braces >( and <(? Does it somehow influence the evaluation of the the if? Or is only -z $OPTIONtested?

Can I understand what's going on better if I write the outputted file of command2 to the disk, then check for the option and read it again in the if statement?

command2 "$OTHER_DETAILS" --out=file.txt
if [ -z "$OPTION]
    command1 --defaultOption --in=file.txt 2>function1
    command1 "$OPTION" --in=file.txt 2>function1

This is part of a script I found over there: http://linuxtv.org/wiki/index.php/V4L_capturing/script (lines 912 through 924)


<(cmd) and >(cmd) are shell grammar (called process substitution). They are replaced by a file path i.e.

cmd1 <(cmd2)


cmd1 /path/to/file

The content of the file is the output of cmd2 thus it can be read only but not written to. An example:

start cmd:> ls -l <(echo foo)
lr-x------ 1 hl hauke 64  5. Jan 03:49 /dev/fd/63 -> pipe:[3125128]

In this case ls sees /dev/fd/63 as an argument. In your case this path becomes part of a redirection. Thus the whitespace is mandatory. > >(cmd) is "redirect stdout to a temprary file which contents become the input of cmd" whereas >>(cmd) causes an error because the shell expects a path (or whitespace) after >>. >>'(cmd)' "works" because now (cmd) is considered a file:

start cmd:> echo foo >>'(cat)'

start cmd:> cat \(cat\) 
| improve this answer | |

A >( ) is an idiom called "Process Substitution" and is used to replace some code or function for "the place of a file".

The >( function1 "$DETAILS" ) is connecting to the stdin of function1. Judging by the name I assume that function1 is a function already defined (in code read before where the function is being used) in the script you are using/reading. Any command that so choose to connect to stdin (many times cat) inside function1 will read the input from stdin

Similarly, <( command2 "$OTHER_DETAILS" ) is connecting to the stdout of command2 (which, I will assume, is a function inside the script). Any echo, printf and many other could write to such stdout from inside the code of command2.

The end result is that the stderr (2>) of the code executed inside the if if being connected to some other code inside the script. And, the output of the command2 is also being connected to code inside the if (which must be command1 judging by the code you presented).

Both re-directions are similar (not exactly equal) to this code:

command2     | command1
command1 2>1 | function1 
| improve this answer | |
  • you need to write command 2's stderr into function 1 as well in your straight-forward example to make it really like. good answer though – mikeserv Jan 5 '16 at 5:42

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.