Nieoczekiwane uzupełnienie globu Bash używa pierwszego dopasowania, nawet jeśli jest niejednoznaczne

3

Jeśli w katalogu mam następujące pliki:

$ ls
a-file-1
b-file-2
something-else

I piszę

$ cat *file*<TAB>

Linia niespodziewanie aktualizuje się

$ cat a-file-1 |

(potok oznacza kursor), chociaż glob również pasuje b-file-2. Trochę dziwniejsze jest to, że jeśli uruchomię inną powłokę, zamiast tego otrzymam listę meczów na podwójnej PATKA (które wolę):

$ cat *file*<TAB><TAB>
a-file-1  b-file-2
$ cat *file*|

P: Jak skonfigurowano to zachowanie? Chciałbym mieć drugie zachowanie w powłoce logowania.

Wygląda na to, że powłoki powłoki uzyskują pierwsze zachowanie, a powłoki inne niż logowania uzyskują drugie. Jednak mój ~/.bash_profile robi niewiele więcej niż rozpoczęcie ~/.bashrc. (Nie mam .profile.) Wydaje się, że w jakiś sposób muszę zmienić konfigurację.

The shopt różnice są takie, że tylko powłoka logowania ma extglob on, hostcomplete off, i login_shell on ale ich zmiana nie zmienia powyższego zachowania. set -o wyjście jest takie samo. Wypróbowany set show-all-if-ambiguous on ale to nie miało żadnego skutku. Używam Ubuntu 14.04.1.

Aktualizacja Jeżeli chodzi o komentarz @mpy .

W powłoce niezalogowanej, gdy dołączam do globu katalog podstawowy i wciskam Alt-G, zachowanie jest inne niż gdy używam PATKA PATKA . To właśnie to ostatnie zachowanie chcę skonfigurować w powłoce logowania.

Alt - sol :

$ ls dir/*file*<Alt-G>

aktualizacje do

$ ls dir/|

usuwanie globu i nie drukowanie żadnych dopasowań. Natomiast PATKA PATKA wyświetla mecze

$ ls dir/*file*<TAB><TAB>
a-file-1  b-file-2
$ ls dir/*file*|
G-Wiz
źródło
Sprawdź, czy powiązania klawiszy są różne ( bind -P ). Mogę odtworzyć zachowanie Twojej powłoki logowania. Ale używając Alt-G ( glob-complete-word ) zamiast TAB ( complete ) Dostaję drugie zachowanie.
mpy
@mpy dziękuję. Interesujące, ale nie wydaje się być przyczyną. bind -P wyjście z obu muszli jest identyczne. Również zachowanie glob-complete-word jest trochę inny niż to, co widzę w powłoce bez logowania za pomocą TAB-TAB. Zaktualizowałem swoją odpowiedź, aby wyjaśnić.
G-Wiz

Odpowiedzi:

2

W Ubuntu 14.04 domyślnie otrzymuję okropne zachowanie przy pierwszym dopasowaniu, ale myślę, że to wina czegoś w programowalnym uzupełnieniu.

Po shopt -u progcomp, Dostaję ładne zachowanie związane z listami rozszerzeń.

Zachowanie użytkownika związane z logowaniem i brakiem logowania jest prawdopodobnie spowodowane uzyskaniem .bash_profile i /etc/profile, albo nie. (Lub twoja powłoka logowania się nie dostanie /etc/bash.bashrc lub .bashrc, jeśli Twój profil go nie obsługuje /).

aktualizacja: śledzono błąd w programowalnym zakończeniu: włączony set -xi spojrzał na wynik wszystkich poleceń, które zostały uruchomione po trafieniu TAB. Znaleziono tam, gdzie globalne wyrażenie zamieniło się w listę i znalazło to w /usr/share/bash-completion/bash_completion

Problem był tutaj: (wyszukaj xspec, aby znaleźć te linie)

xspec=${1:+"!*.@($1|${1^^})"}
x=$( compgen -f -X "$xspec" -- "$quoted" ) &&

"$quoted" brakowało cudzysłowów, więc było to rozszerzane tam, w funkcjach powłoki przetwarzania zakończenia. $quoted jest używany wewnątrz podwójnych cudzysłowów w innym miejscu skryptu, więc jestem przekonany, że powinien być cytowany, i to był właściwy sposób, aby to naprawić.

zgłoszone jako https://bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1387057 , miejmy nadzieję, że zostanie naprawiony w górę i wkrótce trafi do wszystkich dystrybucji.

Peter Cordes
źródło
Dodawanie shopt -u progcomp do .bashrc wydaje się, że wykonał tę sztuczkę. To dziwne, ponieważ shopt nie zgłosił tego inaczej w moich środowiskach. Świetne znalezisko z cytowanym błędem.
G-Wiz
1
shopt -u progcomp wyłącza programowalne zakończenie ... Właśnie mówiłem to jako sposób na sprawdzenie, czy zachowanie pochodzi z programowalnego uzupełnienia, czy nie.
Peter Cordes
Ach, dzięki. bash zaskakuje mnie. Więc jeśli dotrzymam progcomp włączone i dodaj cytaty do bash_completion, Nie dostaję ani rozszerzenia pierwszego meczu, ani zachowanie listy-ekspansji. Kiedy trafię TAB (raz lub dwa razy), nic się nie dzieje. Jeśli jednak wykonam bash, Dostaję rozszerzenie listy na podwójnej TAB (ale set -x nic dziwnego nie daje). Czy masz jakieś dalsze wskazówki?
G-Wiz
1
och, hmm, nie zauważyłem, że bash bez programowalnego zakończenia ma całkiem niezłe zachowanie z wyrażeniami glob. Jeśli wolisz globalne zachowanie niż progcom, wyłącz program progcomp. progcomp daje ci takie rzeczy, jak umiejętność uzupełniania kart przez człowieka ab [TAB] = & gt; polecenia comp na lub git c [TAB] = & gt; komp na polecenia git. I esp. sudo ifc [TAB] = & gt; zakończ na komendach. Również rzeczy takie jak find - [TAB] = & gt; uzupełnij opcje. Wiele komend ma inteligentne programy obsługi, które czasami zapisują stronę podręcznika.
Peter Cordes
1
w zasadzie istnieją 2 tryby, w których możesz być: programowalne uzupełnianie wszystkich załadowanych funkcji powłoki lub bez tego. Wybierz źródło /etc/profile.d/bash_completion, lub nie, z ~ / .bashrc lub /etc/bash.bashrc. (może również wyłączyć po załadowaniu, z shopt -u progcomp lub kompletnym -r.)
Peter Cordes
3

Oprócz niecytowanego „$ quoted” wspomnianego @ peter-cordes, jest jeszcze jeden błąd w funkcji _filedir ():

--- /usr/share/bash-completion/bash_completion--OLD 2015-08-19 19:58:22.734667377 -0500
+++ /usr/share/bash-completion/bash_completion      2016-01-05 15:56:50.442988910 -0500
@@ -604,6 +604,8 @@
         # 2>/dev/null for direct invocation, e.g. in the _filedir unit test
         compopt -o filenames 2>/dev/null
         COMPREPLY+=( "${toks[@]}" )
+    else
+        compopt -o bashdefault 2>/dev/null
     fi
 } # _filedir()

Dzięki temu możesz zjeść swoje ciastko i mieć je również: możesz zachować swój „shopt -s progcmp” bash_completion I jeśli nie znajdzie dopasowania, powróci do używania domyślnej obsługi globu basha.

Dabe Murphy
źródło
To jest świetne! Myślę, że po prostu muszę uważać na aktualizacje pakietu do ukończenia basha.
G-Wiz