`eval` pollutes the history when it runs "set -o history"

classic Classic list List threaded Threaded
6 messages Options
_y
Reply | Threaded
Open this post in threaded view
|

`eval` pollutes the history when it runs "set -o history"

_y
Configuration Information:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -march=x86-64 -mtune=generic -O2 -pipe
-fstack-protector-strong -fno-plt
-DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/bin'
-DSTANDARD_UTILS_PATH='/usr/bin' -DSYS_BASHRC='/etc/bash.bashrc'
-DSYS_BASH_LOGOUT='/etc/bash.bash_logout' -DNON_INTERACTIVE_LOGIN_SHELLS
-Wno-parentheses -Wno-format-security
uname output: Linux mycomputer 5.1.5-arch1-2-ARCH #1 SMP PREEMPT Mon May
27 03:37:39 UTC 2019 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.0
Patch Level: 7
Release Status: release

Description:
        When `eval` runs "set -o history", subsequent lines in the
        eval-ed string are recorded in the history.

        This breaks the following coding pattern:
                saved_options="$(set +o)" # save shell options
                ... # do some things with custom shell options
                eval "$saved_options" # restore shell options
        Indeed, if history is enabled (which is very likely), then the
        output of "set +o" will include the line "set -o history",
        followed by lines for enabling or disabling other options, and
        these following lines pollute the user’s history.

        What makes me think it is an actual bug is that when the
        "history" option was already enabled, "set -o history" should
        have no effect; yet lines before are not recorded, and lines
        after are recorded.

Repeat-By:
        $ env -i bash --norc --noprofile
        $ set -o | grep history
        history        on
        $ eval '
        > echo A         # this line is not recorded (expected behavior)
        > echo B         # neither is this one
        > set -o history # nor that one
        > echo C         # this line is recorded in the history
        > echo D         # this line is recorded in the history
        > '

Reply | Threaded
Open this post in threaded view
|

Re: `eval` pollutes the history when it runs "set -o history"

Chet Ramey
On 6/8/19 3:41 PM, [hidden email] wrote:

> Bash Version: 5.0
> Patch Level: 7
> Release Status: release
>
> Description:
> When `eval` runs "set -o history", subsequent lines in the
> eval-ed string are recorded in the history.

Yes. History doesn't require an interactive shell to work; you can save
commands in the history list and use the history commands to operate on
them in any shell that runs `set -o history'.

>
> This breaks the following coding pattern:
> saved_options="$(set +o)" # save shell options
> ... # do some things with custom shell options
> eval "$saved_options" # restore shell options
> Indeed, if history is enabled (which is very likely), then the
> output of "set +o" will include the line "set -o history",
> followed by lines for enabling or disabling other options, and
> these following lines pollute the user’s history.
>
> What makes me think it is an actual bug is that when the
> "history" option was already enabled, "set -o history" should
> have no effect; yet lines before are not recorded, and lines
> after are recorded.

Bash temporarily stops recording commands in the history when you use
`eval', but if you turn history back on explicitly using `set -o history',
it will honor that.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    [hidden email]    http://tiswww.cwru.edu/~chet/

_y
Reply | Threaded
Open this post in threaded view
|

Re: `eval` pollutes the history when it runs "set -o history"

_y
Chet Ramey wrote (2019-06-10 15:22):

> On 6/8/19 3:41 PM, [hidden email] wrote:
>>
>> What makes me think it is an actual bug is that when the
>> "history" option was already enabled, "set -o history" should
>> have no effect; yet lines before are not recorded, and lines
>> after are recorded.
>
> Bash temporarily stops recording commands in the history when you use
> `eval', but if you turn history back on explicitly using `set -o history',
> it will honor that.
In that case, shouldn’t `eval "set -o"' report that the "history" option
is off while `eval' is running? Currently, it says me that it is on.

While we are at it, are there other special behaviors of `eval` that one
should be aware of, particularly regarding doing `eval $(set +o)' ? The
manual does not say much about the `eval' builtin.

Thanks for your input! (and for Bash, of course)

--
@_y


signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: `eval` pollutes the history when it runs "set -o history"

Chet Ramey
On 6/11/19 9:38 AM, [hidden email] wrote:

> Chet Ramey wrote (2019-06-10 15:22):
>> On 6/8/19 3:41 PM, [hidden email] wrote:
>>>
>>> What makes me think it is an actual bug is that when the
>>> "history" option was already enabled, "set -o history" should
>>> have no effect; yet lines before are not recorded, and lines
>>> after are recorded.
>>
>> Bash temporarily stops recording commands in the history when you use
>> `eval', but if you turn history back on explicitly using `set -o history',
>> it will honor that.
>
> In that case, shouldn’t `eval "set -o"' report that the "history" option
> is off while `eval' is running? Currently, it says me that it is on.
Maybe. But the user-visible option that says whether or not to save
commands in the history is decoupled from the internal set of flags that
control it. The option should remain visibly on unless the user turns it
off, even if saving commands in the history is temporarily suppressed. The
thing is that enabling history with `set -o history' turns all of these
things on.

> While we are at it, are there other special behaviors of `eval` that one
> should be aware of, particularly regarding doing `eval $(set +o)' ? The
> manual does not say much about the `eval' builtin.

It's not clear, since eval just reads and executes commands. The answer
really depends on the commands you give it.


--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    [hidden email]    http://tiswww.cwru.edu/~chet/


signature.asc (201 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: `eval` pollutes the history when it runs "set -o history"

Andreas Schwab
On Jun 11 2019, Chet Ramey <[hidden email]> wrote:

> Maybe. But the user-visible option that says whether or not to save
> commands in the history is decoupled from the internal set of flags that
> control it. The option should remain visibly on unless the user turns it
> off, even if saving commands in the history is temporarily suppressed. The
> thing is that enabling history with `set -o history' turns all of these
> things on.

But should the effect of `set -o history' be deferred until the end of
the temporary suppression?

Andreas.

--
Andreas Schwab, SUSE Labs, [hidden email]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

Reply | Threaded
Open this post in threaded view
|

Re: `eval` pollutes the history when it runs "set -o history"

Chet Ramey
On 6/11/19 10:07 AM, Andreas Schwab wrote:

> On Jun 11 2019, Chet Ramey <[hidden email]> wrote:
>
>> Maybe. But the user-visible option that says whether or not to save
>> commands in the history is decoupled from the internal set of flags that
>> control it. The option should remain visibly on unless the user turns it
>> off, even if saving commands in the history is temporarily suppressed. The
>> thing is that enabling history with `set -o history' turns all of these
>> things on.
>
> But should the effect of `set -o history' be deferred until the end of
> the temporary suppression?

It's ambiguous. `set -o history' has clearly-defined effects and can be
used while the shell is not interactive.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    [hidden email]    http://tiswww.cwru.edu/~chet/