command-not-found handler is invoked from sourced scripts

Bug #559060 reported by Tom Womack
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Gnu Bash
Invalid
Undecided
Unassigned
command-not-found
Won't Fix
Medium
Dominique Ramaekers

Bug Description

I have a program progress.sh which produces an output progress.txt, and seem to type '. progress.txt' rather than '. progress.sh' about once a day.

'. progress.txt' ends up invoking command-not-found several hundred times, and so you have to hold down ctrl-C for some seconds to stop it; would it be possible for command-not-found to be a quick no-op if it's been run more than five times in the last five seconds?

(for a test case, do 'primes 100 1000 > P' then '. P', and try to stop the output with ctrl-C)

Tags: wishlist
Revision history for this message
Zygmunt Krynicki (zyga) wrote :

Interesting, it seems that using . (aka source) in interactive scripts still triggers c-n-f handler! I think this is a bug in bash to be honest, it should not work like that.

Changed in command-not-found:
status: New → Confirmed
summary: - rate-limiting would be nice
+ command-not-found handler invoked from sourced scripts
summary: - command-not-found handler invoked from sourced scripts
+ command-not-found handler is invoked from sourced scripts
Changed in command-not-found:
importance: Undecided → Medium
Revision history for this message
CarstenHey (c.hey) wrote :

Actually, even in executed scripts bash and zsh run their command-not-found handlers, and this is not a bug in bash, but a wonderful feature (e.g., to run scripts in embedded environments with busybox's binary installed but no symlinks to busybox set up). I don't know any real-world use case for zsh's handler (both work differently and their name differs too), but I also think that zsh is correct in running it.

For sourced scripts, the argumentation is similar.

To fix this bug, the handler function should check if a script is sourced, and if it is sourced, the handler function should behave as if the command-not-found binary would be missing.

Revision history for this message
CarstenHey (c.hey) wrote :

This is not a bash issue, see my comment in LP#559060

Changed in gnubash:
status: New → Invalid
Revision history for this message
Dominique Ramaekers (dominique-ramaekers) wrote :

I've investigated this error. I understand it as follows:
- progress.txt has as content some data. For example
      Completed 5%
      Completed 10%
      Completed 15%
      ...
- If Tom executes '. progress.txt' by accident, he gets for every line the result of a c-n-f lookup for 'Completed'.
- I agree, this can be annoying and understand that he would like to see this fixed.

The problem here is that command-not-found can't know if progress.txt was executed as sourced script because bash only returns the faulty command (being 'Completed') to the command_not_found_handle function...
Therefor, this can't be fixed in the package command-not-found.

Not wishing to make this a childish yes/no discussion, I still think the behavior of bash should change:
If a users runs a script as being sourced, it is generally to export a bunch of variables. Even if normal commands/executables are used, bash still should not invoke the c-n-f handle as bash also doesn't do with normally executed scripts.
If a sourced script is used inside a script, bash already won't invoke the c-n-f handle on a faulty command...

Revision history for this message
CarstenHey (c.hey) wrote : Re: [Bug 559060] Re: command-not-found handler is invoked from sourced scripts

* Dadio [2016-01-02 19:28 -0000]:
> I've investigated this error. I understand it as follows:
> - progress.txt has as content some data. For example
> Completed 5%
> Completed 10%
> Completed 15%
> ...
> - If Tom executes '. progress.txt' by accident, he gets for every line
> the result of a c-n-f lookup for 'Completed'.
> - I agree, this can be annoying and understand that he would like to
> see this fixed.
>
> The problem here is that command-not-found can't know if progress.txt
> was executed as sourced script because bash only returns the faulty
> command (being 'Completed') to the command_not_found_handle
> function...
>
> Therefor, this can't be fixed in the package command-not-found.
>
> Not wishing to make this a childish yes/no discussion, I still think
> the behavior of bash should change:
>
> If a users runs a script as being sourced, it is generally to export
> a bunch of variables. Even if normal commands/executables are used,
> bash still should not invoke the c-n-f handle as bash also doesn't do
> with normally executed scripts.
>
> If a sourced script is used inside a script, bash already won't invoke
> the c-n-f handle on a faulty command...

What if I want to source a script in a jail with a c-n-f handler set up
in order to get a list programs I need to install to be able to run the
script?

What if I use busybox in a c-n-f handler as fallback for programs I did
not install but which are shipped as part of my busybox
multi-call-binary?

A c-n-f- handler can be used in more ways than only the most obvious
one, and if bash ever changes the described behaviour, I hope that there
will be an option to restore the current behaviour.

Regards
Carsten

Revision history for this message
Dominique Ramaekers (dominique-ramaekers) wrote :

@CarstenHey, Ok point taken...

@Tom, maybe a little late after 5 years, but a easy workaround:
You can temporarily shutoff the command-not-found hanlder in your session by unsetting the function like this

unset -f command_not_found_handle

Changed in command-not-found:
assignee: nobody → Dadio (dominique-ramaekers)
Changed in command-not-found:
status: Confirmed → In Progress
Revision history for this message
Dominique Ramaekers (dominique-ramaekers) wrote :

So I did some investigating. To make a long story short:

If you invoke a command that is unknown to bash, it tries to execute the function named command_not_found_handle.

On most systems, the function command_not_found_handle is not set on a non-interactive shell ( => so, if you run a script)

If you source a script in a interactive shell, the function command_not_found_handle is set and therefore it is used when the sourced script contains unknown commands.

Referring to Hey's comment #5 and Dan Douglas comment here http://lists.gnu.org/archive/html/bug-bash/2016-12/msg00108.html, it's not wise to change the behaviour of the command-not-found script without a good reason.

Changed in command-not-found:
status: In Progress → Won't Fix
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.