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.