bug-bash
[Top][All Lists]
Advanced

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

Re: eval doesn't close file descriptor?


From: Matei David
Subject: Re: eval doesn't close file descriptor?
Date: Tue, 12 Feb 2013 14:07:28 -0500

So in other words, you're saying I should use '... | eval "exec $x>&-;
llfd"' instead of '... | eval "llfd $x>&-"'. This way the subshell won't be
assuming I might use $x later. That works, but I still find it
counterintuitive that with the original syntax the subshell doesn't realize
there's nothing left to execute after $x>&-.

Also, I tried your other suggestions. The second one 'llfd () { bash -c
.... }' works, but the other 'llfd () ( ... )' doesn't! I tried to
understand why...

Looking at this:
$ bash -c 'llfd () { echo "pid:$BASHPID" >&2; ls -gG /proc/$BASHPID/fd >&2;
}; f () { llfd; (llfd); bash -c "echo pid:\$\$ >&2; ls -gG /proc/\$\$/fd
>&2"; }; x=3; exec 4>/tmp/fd_4; coproc cat; eval "exec $x>/tmp/fd_3"; llfd;
echo | eval "f $x>&-"'
pid:14920
total 0
lrwx------ 1 64 Feb 12 14:03 0 -> /dev/pts/2
lrwx------ 1 64 Feb 12 14:03 1 -> /dev/pts/2
lrwx------ 1 64 Feb 12 14:03 2 -> /dev/pts/2
l-wx------ 1 64 Feb 12 14:03 3 -> /tmp/fd_3
l-wx------ 1 64 Feb 12 14:03 4 -> /tmp/fd_4
l-wx------ 1 64 Feb 12 14:03 60 -> pipe:[5010928]
lr-x------ 1 64 Feb 12 14:03 63 -> pipe:[5010927]
lr-x------ 1 64 Feb 12 14:03 8 -> /proc/4520/auxv
pid:14924
total 0
lr-x------ 1 64 Feb 12 14:03 0 -> pipe:[5007145]
lrwx------ 1 64 Feb 12 14:03 1 -> /dev/pts/2
l-wx------ 1 64 Feb 12 14:03 10 -> /tmp/fd_3
lrwx------ 1 64 Feb 12 14:03 2 -> /dev/pts/2
l-wx------ 1 64 Feb 12 14:03 4 -> /tmp/fd_4
lr-x------ 1 64 Feb 12 14:03 8 -> /proc/4520/auxv
pid:14926
total 0
lr-x------ 1 64 Feb 12 14:03 0 -> pipe:[5007145]
lrwx------ 1 64 Feb 12 14:03 1 -> /dev/pts/2
l-wx------ 1 64 Feb 12 14:03 10 -> /tmp/fd_3
lrwx------ 1 64 Feb 12 14:03 2 -> /dev/pts/2
l-wx------ 1 64 Feb 12 14:03 4 -> /tmp/fd_4
lr-x------ 1 64 Feb 12 14:03 8 -> /proc/4520/auxv
pid:14928
total 0
lr-x------ 1 64 Feb 12 14:03 0 -> pipe:[5007145]
lrwx------ 1 64 Feb 12 14:03 1 -> /dev/pts/2
lrwx------ 1 64 Feb 12 14:03 2 -> /dev/pts/2
l-wx------ 1 64 Feb 12 14:03 4 -> /tmp/fd_4
lr-x------ 1 64 Feb 12 14:03 8 -> /proc/4520/auxv


... there seem to be not 2 but 3(!) types of file descriptors:
1. fds which are copied across both subshells and exec; like 4
2. fds which are not copied across subshells; like 60&63
3. fds which are copied across subshells, but not exec; like 10

I knew about types 1&2, but not about type 3. Apparently with your first
suggestion, fd 10 is created and survives a subshell creation. Is this
correct??


On Tue, Feb 12, 2013 at 11:40 AM, Pierre Gaston <pierre.gaston@gmail.com>wrote:

>
>
> On Tue, Feb 12, 2013 at 6:07 PM, Matei David <matei.david@gmail.com>wrote:
>
>> Ok, but I see the same behaviour when eval runs in a subshell:
>>
>> $ bash -c 'llfd () { echo "pid:$BASHPID" >&2; ls -l /proc/$BASHPID/fd/
>> >&2; }; x=3; eval "exec $x>/dev/null"; llfd; echo | eval "llfd $x>&-"'
>> [same output, fd 10 open, pointing to /dev/null, even though it's a
>> subshell]
>>
>
> eval runs in a subshell, but it's the same thing inside this subshell.
> eg you could have: echo | { eval "llfd "$x>&-"; echo blah >&3; }
>
> Bash could optimize this once it realizes there's only one command, but
> it's probably not that simple to implement.
>
> Try with a function that spawns a subshell eg:
> llfd () (  echo "pid:$BASHPID" >&2; ls -l /proc/$BASHPID/fd/ >&2; )
>
> or llfd () { bash -c 'ls -l /proc/$$/fd' ; }
>
>
>


reply via email to

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