Moje polecenie „które” może być nieprawidłowe (czasami)?


17

Skompilowałem ostatnią wersję emacsa z kodu źródłowego (v24.2), ponieważ wersja zainstalowana na moim komputerze jest dla mnie (dość) stara (v21.3). Zrobiłem zwykle:

$configure --prefix=$HOME
make 
make install

Teraz testuję emacsa i zdałem sobie sprawę, że nadal uruchamia poprzednią wersję ... podczas gdy moja $HOME/binścieżka powinna zastąpić systemową (ponieważ w moim .bashrcpliku jest ona poprzedzona wartością $ PATH ).

Moją pierwszą myślą było zobaczyć whichwyjście polecenia. I niespodzianka, daje ścieżkę do nowych emacs. Nie rozumiem, gdzie jest ta rozbieżność. W tej samej sesji są różne wyniki:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

Nie mam pseudonimu dotyczącego emacsa. W ogóle.

$ alias | grep emacs
$

Masz pomysł, co się dzieje?


co zwraca emacs?
— Ulrich Dangel

Odpowiedzi:


29

Trzy możliwości, które przychodzą mi na myśl:

  • Istnieje alias emacs( dla którego sprawdziłeś)
  • Istnieje funkcja dla emacs
  • Nowy emacsplik binarny nie znajduje się w tablicy skrótów PATH twojej powłoki.

Możesz sprawdzić, czy masz funkcję emacs:

bash-3.2$ declare -F | fgrep emacs
declare -f emacs

I usuń to:

unset -f emacs

Twoja powłoka ma również tablicę mieszającą PATH, która zawiera odniesienie do każdego pliku binarnego w PATH. Jeśli dodasz nowy plik binarny o takiej samej nazwie jak istniejący gdzie indziej w PATH, powłoka musi zostać poinformowana poprzez aktualizację tablicy hashtable:

hash -r

Dodatkowe wyjaśnienie:

which nie wie o funkcjach, ponieważ nie jest to wbudowane bash:

bash-3.2$ emacs() { echo 'no emacs for you'; }
bash-3.2$ emacs
no emacs for you
bash-3.2$ which emacs
/usr/bin/emacs
bash-3.2$ `which emacs` --version | head -1
GNU Emacs 22.1.1

Ten skrypt pokazuje nowe binarne zachowanie tablicy hashtable.

bash-3.2$ PATH=$HOME/bin:$PATH
bash-3.2$ cd $HOME/bin

bash-3.2$ cat nofile
cat: nofile: No such file or directory
bash-3.2$ echo echo hi > cat
bash-3.2$ chmod +x cat
bash-3.2$ cat nofile
cat: nofile: No such file or directory

bash-3.2$ hash -r
bash-3.2$ cat nofile
hi
bash-3.2$ rm cat
bash-3.2$ cat nofile
bash: /Users/mrb/bin/cat: No such file or directory

bash-3.2$ hash -r
bash-3.2$ cat nofile
cat: nofile: No such file or directory

Chociaż nie nazwałem go, which catzawsze zwracałbym pierwszy catw mojej ŚCIEŻCE, ponieważ nie używa on tablicy hashującej powłoki.


1
Chociaż są tutaj dobre informacje, brakuje typepolecenia.
— jordanm

Dzięki, miałem ten sam problem ze świeżo skompilowaną wersją sqlite3, co doprowadziło mnie do szału (co faktycznie zwróciło właściwą ścieżkę, ale powłoka nie wywołała właściwego sqlite3 cli). hash -rnaprawił mój problem.
— mpm

12

Tak, nie używaj które :

  • W niektórych systemach jest to polecenie zewnętrzne zaimplementowane jako skrypt csh, który może odczytać konfigurację zmieniającą PATH.
  • Jest do tego wbudowany. Dwa, nawet: typei command. Sposób POSIX:

    command -v emacs       # machine-readable format
    type emacs             # human-only format

    W bash możesz także użyć, type -p emacsaby zobaczyć tylko ścieżkę zewnętrznego polecenia.

Jednak tutaj whichjest właściwie słuszne. Bash przechowuje informacje o lokalizacji polecenia w pamięci, aby następnym razem szybciej wykonać polecenie. Zainstalowałeś emacsna swoim komputerze nowy plik wykonywalny PATH, ale bash nadal ma starą lokalizację w swojej pamięci podręcznej. Uruchom, hash emacsaby emacsponownie wyszukać lub hash -ropróżnić pamięć podręczną.


1

Czy wylogowałeś się i zalogowałeś, aby .bashrcponownie odczytać zaktualizowany plik logowania? Jeśli nie, środowisko twojej bieżącej sesji nie zostało zaktualizowane.


Gdyby tak było, `which emacs` --versionzgodziłby się emacs --version, ponieważ whichdziedziczy swoją ŚCIEŻKĘ z bieżącej powłoki.
— mrb

@mrb: Punkt dobrze zajęty.
— JRFerguson
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.