Próbuję przejść do irb
sesji z określonymi zmiennymi środowiskowymi z pliku za pomocą tego polecenia:
$ env $(cat env.sh) irb
Ale kiedy próbuję nacisnąć Tab
po wpisaniu, env.
aby go ukończyć, pojawia się następujący błąd:
$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file
Inną interesującą rzeczą jest to, że jeśli jestem zalogowany jako root, ten błąd nie występuje.
Oto wynik find ~ -uid 0
:
$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003
Czy ktoś może mi wyjaśnić, dlaczego tak się dzieje, a jeśli tak, to jak to naprawić, gdy nie jestem użytkownikiem root?
command-line
bash
auto-completion
Eldosoa
źródło
źródło
sudo su
.find ~ -uid 0
.~
jest/home/something
.Odpowiedzi:
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 toapt-get install
. Jeśli nie podasz tej biblioteki, masz tylko standardowe, prymitywne uzupełnianie basha - więc na przykład, jeśli wpiszeszapt-get i
Tabbez źródła, bash po prostu wyszuka pliki w bieżącym katalogu zaczynając odi
i spróbuje wykonać polecenie zgodnie z te nazwy plików.Dlaczego to się nie dzieje jako root?
Ponieważ kiedy używasz
sudo su
siebieroot
, 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 jakoroot
, 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:
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: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 piszeszenv $(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
w ramach funkcji
_quote_readline_by_ref
w pliku/usr/share/bash-completion/bash_completion
przy liniiNie 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:... 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.
źródło
sudo su
roota, nie pobiera on biblioteki, ale będzie pozyskiwany, gdy go użyjeszsudo -i
, co jest zamierzonym sposobem uzyskania interaktywnej sesji rootowania. Jeśli chodzi o twoje pytanie: ponieważ jakakolwiek powłoka bash czyta,~/.bashrc
co ostatecznie pobiera bibliotekę, i nie ma sposobu na „cofnięcie źródła” pliku, nie widzę całkowicie prostego sposobu. Oto możliwe Hack: Dokonać pozyskiwania warunkowego biblioteki na jakiejś zmiennej środowiskowej, powiedzmyNOCOMPL
, nie jest zdefiniowana na liście~/.bashrc
...