[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: when output of <( ... ) is stored in function argument, it can be us
From: |
Kerin Millar |
Subject: |
Re: when output of <( ... ) is stored in function argument, it can be used only once - why? |
Date: |
Tue, 24 Jan 2023 08:50:08 +0000 |
On Tue, 24 Jan 2023 09:23:37 +0100
Ante Bilandzic <abilandzic@gmail.com> wrote:
> Hello,
>
> Please can somebody answer the question in the subject line, or point me to
> relevant documentation where the underlying mechanism at work is explained?
>
> It is reduced to the bare bones with the following one-liner:
>
> $ what(){ wc -l $1; wc -l $1; }; what <(ls)
> 18 /dev/fd/63
> 0 /dev/fd/63
>
> In my particular case, 18 is the correct number of lines in the output of
> <(ls). Why the 2nd and identical execution of 'wc -l' doesn't also get it
> right?
The sequence of events is approximately as follows.
1) Through process substitution, you set up a named pipe with ls as a writing
process.
2) You pass the name of this pipe to the what function.
3) wc instance #1 reads the pipe, until it encounters EOF, indicating that
there is nothing more to be read.
4) wc instance #2 reads the pipe, immediately encountering EOF (because ls has
closed its end at this point).
5) wc instance #2, having read nothing, correctly reports 0 lines.
6) Finally, the reading end of the pipe is closed and the pipe is rendered
defunct.
Essentially, there is no way to make your example work as you expect. Were it a
case of reading from a regular file, it would be possible to use a syscall such
as fseek(3) to situate the file position indicator at the beginning of the file
again, before reading it a second time in full. However, bash does not offer a
usable abstraction for that particular syscall. Besides, it is impossible to
seek for a file descriptor that refers to a pipe.
--
Kerin Millar