-
Notifications
You must be signed in to change notification settings - Fork 386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aborting a completion attempt leaves set -o noglob
in effect
#786
Comments
Hmph, yeah, I can see how that would happen. Semi-related: #739 |
I have thought the same thing after I first read this issue and tried it, but
|
Would
I'm not sure I follow, but wouldn't this leave the altered state in effect for the user's shell until the next call of the completion? |
I think the problem with recovering the options could be solved, but then there arises another problem of the completion that can take a long time not being able to be canceled. Specifically, OP describes the case where the filename completion is attempted in a directory with many files on remote filesystems. sidenote: implementation in ble.shI now remembered that I have implemented in ble.sh more complicated processing for this issue of slow filename completions. I attempt the pathname expansions (aka glob expansions) in a background subshell, and wait for its termination or user inputs in the parent shell. The subshell is killed when there are any user inputs before its termination. In this case, the result needs to be passed to the parent shell after the completion of the pathname expansions. Here, the next problem is how to effectively pass the expansion results to the parent shell. It turned out that Other completions that might take a long time are handled in a similar way separately for each case.
Right. So this is merely a partial solution in case all the other solutions are unavailable. |
It turned out that the $ bash-dev --norc
$ function f1 { trap 'echo f1/ERR:$FUNCNAME' ERR; f2; echo never; false; }; function f2 { sleep 1; }; f1
^Cf1/ERR:f1
$ exit
$ bash-4.4 --norc
$ function f1 { trap 'echo f1/ERR:$FUNCNAME' ERR; f2; echo never; false; }; function f2 { sleep 1; }; f1
^Cf1/ERR:f1
$ exit
$ bash-4.3 --norc
$ function f1 { trap 'echo f1/ERR:$FUNCNAME' ERR; f2; echo never; false; }; function f2 { sleep 1; }; f1
^C
$ edit: Anyway, the user's ERR trap needs to be saved and restored. |
I think another way to make sure to recover the original settings is to recheck them before running the user commands.
Note: All of these approaches might be broken by the user's other settings overwriting We might combine one of the above with #739 |
Describe the bug
Certain completions turn off globbing with
set -o noglob
, perform some operation, and then attempt to reset globbing back to its original state. See for examplebash-completion/bash_completion
Lines 758 to 763 in 36ceb27
Unfortunately if the user presses Ctrl+C in the middle of this then the reset code is never run and the shell is left with
set -o noglob
in effect. This will likely be very disconcerting for the user. For instance, runningls *
reportsls: cannot access *: No such file or directory
. That's the message you'd normally expect to see if the directory is empty but now you'll see it reported for all directories, giving the impression that all of your files have been deleted.A user could recover from this by running
set +o noglob
but they'd have to realize what was wrong first. I'm assuming in most cases people will just think their terminal is "broken" and be forced to close it and open a new one.See also #691 .
To reproduce
You'll need a directory somewhere that's very slow to enumerate. One option would be to mount an NFS directory from some slow, distant machine. Another would be to create a local directory with an absurdly large number of files in it and have a cold cache (possibly something like
echo 3 > /proc/sys/vm/drop_caches
might help on Linux). Or maybe https://serverfault.com/a/954175. I can personally reproduce this with a large directory on NFS.Expected behavior
The
noglob
setting should retain the previous value.Versions (please complete the following information)
echo "$BASH_VERSION"
: 4.2.46(2)-release(IFS=.; echo "${BASH_COMPLETION_VERSINFO[*]}")
: This command outputs "2.11.0", but I'm actually using git commit 36ceb27.Additional context
Maybe this could be handled by running the compgen in a subshell so that the setting would not have to be remembered and then explicitly restored?
Debug trace
I'm going to avoid including entire thing for now since it is large and I don't think it will help explain the problem. If you still need it, please tell me and I'll send the full one. It ends with this, the
compgen
having been interrupted by Ctrl+C:I can't reproduce the problem on a different system that uses bash 5.1. I believe that's because of a recent change to bash, introduced in v5.1, that masks SIGINT during the execution of
compgen
: https://github.com/bminor/bash/blob/9439ce094c9aa7557a9d53ac7b412a23aa66e36b/subst.c#L6542. This makes the code in bash-completion work as expected but has the downside that you can't abort the completion and have to wait for it to finish no matter how long it takes.The text was updated successfully, but these errors were encountered: