Моя команда `котрий` може бути неправильною (іноді)?


17

Я склав останню версію emacs із вихідного коду (v24.2), оскільки версія, встановлена ​​на моїй машині, для мене (досить) стара (v21.3). Я зробив звичайне:

$configure --prefix=$HOME
make 
make install

Тепер я тестую emacs і зрозумів, що він все ще запускає попередню версію ... в той час як мій $HOME/binшлях повинен перекрити систему один (оскільки в моєму .bashrcфайлі це передбачено $ PATH ).

Першою моєю думкою було побачити whichвихід команди. І здивування, це дає шлях до нових емаків. Я не можу зрозуміти, де тут розбіжність. У цьому ж сеансі ось різні результати:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

У мене немає псевдоніму, що стосується emacs. Зовсім.

$ alias | grep emacs
$

Будь-яка ідея, що відбувається, будь ласка?


що повертає emacs?
Ульріх Дангель

Відповіді:


29

Три можливості, які мені спадають на думку:

  • Псевдонім існує для emacs(який ви перевірили)
  • Функція існує для emacs
  • Новий emacsбінарний файл не знаходиться в хеш-пам’яті PATH вашої оболонки.

Ви можете перевірити, чи є у вас функція emacs:

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

І видаліть його:

unset -f emacs

У вашій оболонці також є хешблет PATH, який містить посилання на кожен двійковий код вашої PATH. Якщо ви додасте новий бінарний файл з тим самим іменем, що і існуючий в іншому місці вашого PATH, оболонку потрібно повідомити, оновивши хештеб:

hash -r

Додаткове пояснення:

which не знає про функції, оскільки це не 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

Цей сценарій демонструє нову поведінку бінарних хештелів.

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

Хоча я і не називав це, which catзавжди повертав би перше catв моєму PATH, оскільки він не використовує хеш-пам'ять оболонки.


1
Хоча тут є добра інформація, вона пропускається в typeкоманді.
Йорданм

Дякую, у мене був той самий випуск із щойно складеною версією sqlite3, яка змусила мене "(який насправді повернув правильний шлях, але оболонка не викликала потрібний кліп sqlite3"). hash -rвиправили мою проблему.
mpm

12

Так, не використовуйте :

  • У деяких системах це зовнішня команда, реалізована як csh-скрипт, яка може читати конфігурацію, що змінює PATH.
  • Для цього є вбудований. Два, навіть: typeі command. POSIX спосіб:

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

    У bash ви також type -p emacsможете бачити лише шлях зовнішньої команди.

Однак тут whichнасправді правильно. Bash зберігає інформацію про розташування команди в пам'яті, щоб вона могла виконати команду швидше наступного разу. Ви встановили новий emacsвиконуваний файл на своєму PATH, але bash все ще має старе розташування в своєму кеші. Біжіть hash emacsзнову шукати вгору emacsабо hash -rспорожняти кеш.


1

Ви входили та входили, щоб змусити .bashrcперечитати оновлений файл входу? Якщо ні, то середовище вашого поточного сеансу не оновлено.


Якби це було так, я `which emacs` --versionб погодився emacs --version, тому що він whichуспадковує його PATH від поточної оболонки.
mrb

@mrb: Точка добре взята.
JRFerguson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.