0

While studying bash process substitution, I found this:

counter=0

while IFS= read -rN1 _; do
    ((counter++))
done < <(find /etc -printf ' ')

echo "$counter files"

If I understand correctly, the output of find command substitutes the "_".

However:

  • Which mechanism is this?
  • Additionally: what does read -rN1 do?

Update:

Additional question: The process substitution is pointing to the "done" in the while loop. How does this work, i.e., why would the while loop take a substitution at that place. Is there any thing general I can read about?

1

1 Answer 1

3

<(find /etc -printf ' ') is called "process substitution". It will generate one character (an space ' ') per each file. The output of find /etc -printf ' ' is made available in a file (or something that appears as a file). The name of this file is expanded on the command line. The additional < performs the redirection for stdin from that file.

read -rN1 _ reads from (the redirected) stdin into a variable called _, one character at a time, and count those characters (which each represent one file).

Here are the read arguments from man bash:

-r     Backslash  does not act as an escape character.  The backslash is considered
       to be part of the line.  In particular, a backslash-newline pair may not  be
       used as a line continuation.

-N nchars
       read returns after reading exactly nchars characters rather than waiting for
       a  complete  line  of  input,  unless  EOF is encountered or read times out.
       Delimiter characters encountered in the input are not treated specially  and
       do not cause read to return until nchars characters are read.
6
  • I'm afraid the phrasing above is somewhat fuzzy: "is then read from STDIN into the while loop" and "what the while loop is currently presenting". The loop forms a block or "compound command" whose stdin is redirected from the "process substitution", and read within the block is the only consumer.
    – RudiC
    Dec 5, 2018 at 17:11
  • @RudiC: Great point, thank you. I researched this and concluded that my understanding of how the loop worked was incorrect. Does my latest edit look accurate?
    – Peschke
    Dec 5, 2018 at 17:34
  • I tried an edit to get the phrasing right but adhering as close as possible to your original...
    – RudiC
    Dec 5, 2018 at 22:01
  • if you dont mind, I have one last question and ready to take your answer (let me put it in the main question as well). The process substitution is pointing to the "done" in the while loop. How does this work, i.e., why would the while loop take a substitution at that place. Is there any thing general I can read about?
    – drdot
    Dec 13, 2018 at 19:31
  • @drdot The whole while ... done construct is practically one command, < <(...) just sends the output of <(...) as standard input to the loop. You could (although it's rather silly) also run cat < <(find .tmp -printf '.') to just show the output in the terminal.
    – nohillside
    Dec 13, 2018 at 19:51

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.