0

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 ?

2
  • <(...) alone is not a redirection; it's a process substitution, that exposes the output of a command as if it were a file. the < between done and the process substitution is the redirection operator: it causes the while loop to use the process substitution as its standard input.
    – chepner
    Commented Nov 19, 2022 at 13:32
  • Everything inside the while loop inherits the loop's standard input as its own, which is why each read command reads from the process substitution as well.
    – chepner
    Commented Nov 19, 2022 at 13:33

2 Answers 2

1

<(...) 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.

0

how far does a redirection go in a command line?

The redirection goes for the whole duration of a command it is applied to.

There is shell grammar which defines the basic stuff that are inside a "command line". You can peak at POSIX shell standard and Bash documentation.

A command is one of the following:

Simple command (see Simple Commands)

Pipeline (see Pipelines)

List compound-list (see Lists)

Compound command (see Compound Commands)

Function definition (see Function Definition Command)

A command may be a compound command, which may be a looping construct, which may be a while looping construct. A while is a single, one command.

The redirection is redirected for the whole duration of a command, and inherited for any commands inside that command.

while
    redirected here
do
    redirected here
done < redirection

if
    redirected here
then
    redirected here
else
    redirected here
fi < redirection

etc.

Not the answer you're looking for? Browse other questions tagged or ask your own question.