bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: redirection / process substitution fails to read a file descriptor


From: Mike Peters
Subject: Re: redirection / process substitution fails to read a file descriptor
Date: Sun, 17 Nov 2024 12:16:40 -0600
User-agent: Mozilla Thunderbird

On 2024-11-16 22:56, Lawrence Velázquez wrote:
On Sat, Nov 16, 2024, at 9:35 PM, Greg Wooledge wrote:
On Sat, Nov 16, 2024 at 16:35:05 -0600, Mike Peters wrote:
Description:
         Process substitution does not generate properly when pulling from another file 
descriptor, although it works when pulling from a file directly. In the below sample shell 
session, it is expected that `<(<test.txt)` would be functionally equivalent to 
`<(<&3)`.

Repeat-By:
         > echo foobar > test.txt
         > echo `< <(<test.txt)`
         foobar

Be aware that <(<file) is undocumented and was removed [1] after
Emanuele brought it up [2]; it will not work in future releases.

I don't know what documentation it was missing from, but this usage is consistent and logically valid with 
the manual... Process substitution 'takes the form of <(list) or >(list)'. The grammar defines 'list' 
to be 'a sequence of one or more pipes', a 'pipeline' to be 'a sequence of one or more commands'. Command 
substitution takes the form $(command) or `command`, and since `<file` is valid as specified by the cat 
shortcut, <file must be a valid simple command. SIMPLE COMMAND EXPANSION explicit allows redirections*: 
"If no command name results, redirections are performed, but do not affect the current shell 
environment." Thus the manual's grammar technically does document the validity of <(<file).

I hope it's removal is documented in the manual.

* (Although I have yet to determine any purpose or significance of these redirections in the 
manual, other than simply not causing an error, as it "do[es] not affect the current shell 
environment", and there is "no command name", so what is there remaining to affect?)

However, the "issue" does affect command substitutions:

        $ echo foobar >test.txt
        $ echo "$(<test.txt)"
        foobar
        $ exec 3<test.txt
        $ echo "$(<&3)"

        $

[1] 
https://git.savannah.gnu.org/cgit/bash.git/commit/?h=devel&id=d3e86e66ce857a8dc02e3116fd98b6e5b34d6364
[2] https://lists.gnu.org/archive/html/bug-bash/2024-07/msg00045.html


I'm guessing that the parser sees the <& and decides *not* to treat
this as a shortcut of cat with &3 as a filename.  Therefore, the only
thing the parser can do is treat this as an empty command with a <&3
redirection attached to it.

As I understand the code [3][4], <file ("r_input_direction") is a
candidate for the "cat" optimization, <&n ("r_duplicating_input")
isn't, and the decision is made after parsing, so there's no way
&n could be interpreted as a filename.

Note that the actual documentation for this feature doesn't say or
imply that <&n should work:

        The command substitution $(cat file) can be replaced by the
        equivalent but faster $(< file).

Agreed. I had a mistaken understanding. I took too much liberty in 
interpretation.


This reading doesn't make much sense:

        The command substitution $(cat &n) can be replaced by the
        equivalent but faster $(< &n).

There might be an argument for it if the documentation read:

        The command substitution $(cat <file) can be replaced by
        the equivalent but faster $(<file).

But it doesn't.


I disagree. The REDIRECTION section of the manual uses the word 'word' when it might 
refer to either a file descriptor or a file, so I think "there might be an 
argument" if the declaration involved incorporating 'word' in place of 'file'.

[3] 
https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/evalstring.c?h=devel&id=fa68e6da80970c302948674369d278164a33ed39#n198
[4] 
https://git.savannah.gnu.org/cgit/bash.git/tree/make_cmd.c?h=devel&id=fa68e6da80970c302948674369d278164a33ed39#n663


Mike Peters





reply via email to

[Prev in Thread] Current Thread [Next in Thread]