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 11:07:06 -0500

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]

$ bash -c 'llfd () { echo "pid:$BASHPID" >&2; ls -l /proc/$BASHPID/fd/ >&2;
}; x=3; eval "exec $x>/dev/null"; llfd; echo | llfd 3>&-'
[not the same output; no fds pointing to /dev/null, as expected]

When eval is run by the main shell and I want $x closed, I can just do
'eval "exec $x>&-"'. However, I cannot do that with eval runs in a
subshell. In my script I needed $x open for other processes in that
pipeline.


On a different but related note, I hate having to do eval to manipulate an
fd stored in a variable. Why doesn't 'llfd $x>&-' work, especially since
'llfd >&$x' works just fine... so by the time >& is handled, the variable
substitutions seem to be done already.


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

>
>
> On Tue, Feb 12, 2013 at 1:54 AM, <matei.david@gmail.com> wrote:
>
>> With the script below, I'd expect any fd pointing to /dev/null to be
>> closed when the second llfd() is executed. Surprisingly, fd 3 is closed,
>> but fd 10 is now open, pointing to /dev/null, as if eval copied it instead
>> of closing it. Is this a bug?
>>
>> Thanks,
>> M
>>
>>
>> $ bash -c 'llfd () { ls -l /proc/$BASHPID/fd/; }; x=3; eval "exec
>> $x>/dev/null"; llfd; eval "llfd $x>&-"'
>> total 0
>> lrwx------ 1 matei matei 64 Feb 11 18:36 0 -> /dev/pts/2
>> lrwx------ 1 matei matei 64 Feb 11 18:36 1 -> /dev/pts/2
>> lrwx------ 1 matei matei 64 Feb 11 18:36 2 -> /dev/pts/2
>> l-wx------ 1 matei matei 64 Feb 11 18:36 3 -> /dev/null
>> lr-x------ 1 matei matei 64 Feb 11 18:36 8 -> /proc/4520/auxv
>> total 0
>> lrwx------ 1 matei matei 64 Feb 11 18:36 0 -> /dev/pts/2
>> lrwx------ 1 matei matei 64 Feb 11 18:36 1 -> /dev/pts/2
>> l-wx------ 1 matei matei 64 Feb 11 18:36 10 -> /dev/null
>> lrwx------ 1 matei matei 64 Feb 11 18:36 2 -> /dev/pts/2
>> lr-x------ 1 matei matei 64 Feb 11 18:36 8 -> /proc/4520/auxv
>> $ bash --version
>> GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)
>> Copyright (C) 2011 Free Software Foundation, Inc.
>> License GPLv3+: GNU GPL version 3 or later <
>> http://gnu.org/licenses/gpl.html>
>>
>> This is free software; you are free to change and redistribute it.
>> There is NO WARRANTY, to the extent permitted by law.
>> $
>>
>
> Note that the same happens without using eval:
> $ llfd 3>&-
> total 0
> lrwx------ 1 pgas pgas 64 Feb 12 08:00 0 -> /dev/pts/0
> lrwx------ 1 pgas pgas 64 Feb 12 08:00 1 -> /dev/pts/0
> l-wx------ 1 pgas pgas 64 Feb 12 08:00 10 -> /dev/null
> lrwx------ 1 pgas pgas 64 Feb 12 08:00 2 -> /dev/pts/0
> lrwx------ 1 pgas pgas 64 Feb 12 08:00 255 -> /dev/pts/0
>
> But you need to consider what process you are examining, you use a
> function and you examine the file descriptors of the process where this
> function runs.
>
> A function runs in the same process as the parent shell, if it simply
> closes 3 then there will be no more fd opened on >/dev/null in the parent
> shell when the function returns
> So what bash does is a little juggling with the file descriptors, moving 3
> temporarily to be able to restore it.
>
>
>
>
>
>
>
>


reply via email to

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