Znalazłeś błąd w bibliotece Bash Completion używanej przez Ubuntu.
Co to znaczy?
Ubuntu wykorzystuje bibliotekę zakończenia bash, aby uczynić zakończenie bash inteligentnym. Ta biblioteka mieszka /usr/share/bash-completion/bash_completion
.
Zasadniczo ta biblioteka deklaruje kilka sprytnych funkcji, które znają typowe polecenia i jak je wykonać. Po każdym naciśnięciu Tabwywoływane są funkcje w tej bibliotece i podejmowane są próby uzupełnienia bieżącego wiersza poleceń. Na przykład, jeśli wpiszesz apt-get i
Tab, dokończy to apt-get install
. Jeśli nie podasz tej biblioteki, masz tylko standardowe, prymitywne uzupełnianie basha - więc na przykład, jeśli wpiszesz apt-get i
Tabbez źródła, bash po prostu wyszuka pliki w bieżącym katalogu zaczynając od i
i spróbuje wykonać polecenie zgodnie z te nazwy plików.
Dlaczego to się nie dzieje jako root?
Ponieważ kiedy używasz sudo su
siebie root
, biblioteka ukończenia bash nie jest pozyskiwana. Byłoby inaczej, gdybyś sudo -i
sam się tworzył root
. Założę się, że widzisz wtedy błąd, prawda? Zobacz na przykład „sudo su -” vs ”sudo -i” vs „sudo / bin / bash” - kiedy ma to znaczenie, które jest używane, czy w ogóle ma znaczenie? jeśli nie znasz różnic.
W moim przypadku, jako zwykły użytkownik, biblioteka jest pozyskiwana, gdy uruchamiam powłokę Bash, ponieważ ~/.bashrc
źródła, /etc/bash_completion
które źródła /usr/share/bash-completion/bash_completion
.
Jeśli użyję sudo -i
do logowania jako root
, biblioteka jest pozyskiwana, ponieważ /etc/profile
źródła, /etc/profile.d/bash_completion.sh
które źródła /usr/share/bash-completion/bash_completion
.
Dlaczego ten błąd się dzieje?
Spróbuj wykonać to polecenie:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Wygląda znajomo? ;-) Rzeczywiście, dokładnie tak stało się za kulisami, kiedy trafiłeś Tabw opisany kontekst. Dokładniej, błąd występuje w funkcji _quote_readline_by_ref
zadeklarowanej przez /usr/share/bash-completion/bash_completion
. Jeśli pozyskałeś ten plik, powinieneś mieć dostęp do tej funkcji. Następnie spróbuj tego:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Biorąc pod uwagę te argumenty, funkcja _quote_readline_by_ref
spełnia, między innymi, eval
wspomniane powyżej. Możesz spojrzeć, jeśli chcesz. A kiedy piszesz env $(cat env.
Tab, za kulisami funkcja jest wywoływana z dokładnie tymi argumentami. Tak się stało.
Ten eval
hack miał naprawić inny problem , ale wydaje mi się, że wprowadził ten drugi błąd w tym procesie.
Jak to naprawić?
Okazuje się, że ten błąd został już zgłoszony . Po przeczytaniu tego raportu o błędach widzę trzy sposoby, aby to naprawić:
Popraw to: w jednym z komentarzy w tym raporcie o błędzie ktoś sugeruje zastąpienie linii
[[ ${!2} == \$* ]] && eval $2=${!2}
w ramach funkcji _quote_readline_by_ref
w pliku /usr/share/bash-completion/bash_completion
przy linii
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Nie polecam tego robić. Osoba, która napisała ten komentarz, nie wydaje się być twórcą bash-uzupełniania . Ta poprawka po prostu spowoduje, że lewy argument instrukcji będzie miał wartość false, a tym samym zapobiegnie temu eval
. Jednak bez dobrej wiedzy o tym, co ta funkcja ma robić i w jakich kontekstach się nazywa, nie jest jasne, czy nie spowoduje to potencjalnej awarii innych zamierzonych funkcji.
Pobierz najnowszą wersję: Jak wspomniano również w tym raporcie o błędach, ten błąd nie występuje w git head (gdzie między innymi zmiany _quote_readline_by_ref
zostały uproszczone). Możesz po prostu sklonować bieżącą wersję z Git:
git clone https://salsa.debian.org/debian/bash-completion.git
... a następnie skopiuj najnowszą wersję bash_completion
skryptu na /usr/share/bash-completion
(nie ma potrzeby pilnego tworzenia kopii zapasowej starej wersji, chyba że czujesz się bezpieczniej - jeśli wystąpią problemy, sudo apt-get install --reinstall bash-completion
powinieneś cofnąć wszelkie zmiany, które wprowadziłeś). zalecamy, jeśli spieszysz się, aby to naprawić. :-)
Zauważ, że żadne z tych rozwiązań nie spowoduje zakończenia bashu w ramach zastępowania poleceń: jak wspomniano w tym samym raporcie o błędzie, jest to zepsute w Bash 4.3.
- Usiądź i poczekaj: wcześniej czy później zostanie wydana nowa wersja (która może nawet naprawić uzupełnianie basha w ramach zastępowania poleceń), a otrzymasz ją w przyszłej wersji Ubuntu. Po to idę ;-)