Search code examples
bashio-redirection

how far does a redirection go in a command line?


I would like to undestand where a stdin redirection goes in an expression like < <(cmd)

as a test to learn more about bash I tried to write a bash function with while .. do .. done and to have it working I had to use a trial and error method , mainly because I did not know the behavior or the first redirection in < <(find ...):

while read L ;do basename "$L";((k++));done <  <(
    find -maxdepth 1 -type d -name '.*' |
    sort
)

With only <(find ... it does not work . I suppose it's because stdout of find command line goes to a tmp file ( so I read ) ; so I added one more < to "push" further the copy of stdout . That I can understand , but how can I know that stdout copied in the tmp file does not stop at the first command encountered : basename and goes as far as stdin of while command ?


Solution

  • <(...) by itself is a process substitution. It behaves like a file name, except the "contents" of the file it names are the output of the command. For example,

    $ echo <(echo foo)
    /dev/fd/63
    $ cat <(echo foo; echo bar)
    foo
    bar
    

    A while loop doesn't take arguments, which is why you get a syntax error without the input redirection.

    $ while read x; do echo "$x"; done <(echo foo; echo bar)
    bash: syntax error near unexpected token `<(echo foo; echo bar)'
    

    With the input redirection, the while loop (which is a command, and like any other command, has its own standard input) uses the process substitution as its standard input.

    $ while read x; do echo "$x"; done < <(echo foo; echo bar)
    foo
    bar
    

    while doesn't actually use its standard input, but any command in the while loop inherits its standard input from the loop. That includes read, so each execution of read gets a different line from the file until the file is exhausted, at which point read has an exit status of 1 and the loop terminates.