Perintah `yang` saya mungkin salah (kadang-kadang)?

17

Saya telah mengompilasi versi emacs terakhir dari kode sumber (v24.2) karena versi yang diinstal pada komputer saya (cukup) lama bagi saya (v21.3). Saya sudah melakukan yang biasa:

$configure --prefix=$HOME
make 
make install

Sekarang saya sedang menguji emacs dan menyadari bahwa ia masih meluncurkan versi sebelumnya ... sementara $HOME/binjalur saya seharusnya mengesampingkan sistem satu (karena itu ditanggung oleh $ PATH dalam .bashrcfile saya ).

Pikiran pertama saya adalah melihat whichoutput perintah. Dan mengejutkan, itu memberi jalan ke emacs baru. Saya tidak mengerti di mana perbedaannya di sini. Dalam sesi yang sama di sini adalah keluaran yang berbeda:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

Saya tidak memiliki alias yang melibatkan emacs. Sama sekali.

$ alias | grep emacs
$

Ada yang tahu apa yang sedang terjadi, tolong?

Yves Baume
sumber
apa yang dikembalikan emacs?
Ulrich Dangel

Jawaban:

29

Tiga kemungkinan yang muncul di benak saya:

  • Ada alias untuk emacs(yang sudah Anda periksa)
  • Ada fungsi untuk emacs
  • emacsBiner baru tidak ada dalam hashtable PATH shell Anda.

Anda dapat memeriksa apakah Anda memiliki fungsi emacs:

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

Dan hapus:

unset -f emacs

Shell Anda juga memiliki hashtable PATH yang berisi referensi ke setiap biner di PATH Anda. Jika Anda menambahkan biner baru dengan nama yang sama dengan yang ada di tempat lain di PATH Anda, shell perlu diinformasikan dengan memperbarui hashtable:

hash -r

Penjelasan tambahan:

which tidak tahu tentang fungsi, karena ini bukan bash bawaan:

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

Perilaku hashtable biner baru ditunjukkan oleh skrip ini.

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

Meskipun saya tidak menyebutnya, which catakan selalu mengembalikan yang pertama catdi PATH saya, karena tidak menggunakan hashtable shell.

mrb
sumber
1
Meskipun ada informasi yang baik di sini, itu tidak memenuhi typeperintah.
jordanm
Terima kasih, saya memiliki masalah yang sama dengan versi yang baru dikompilasi dari sqlite3 yang membuat saya gila (yang sebenarnya mengembalikan jalan yang benar, tetapi shell tidak menyebut hak sqlite3 cli). hash -rmemperbaiki masalah saya.
mpm
12

Ya, jangan gunakan yang :

  • Pada beberapa sistem, ini adalah perintah eksternal yang diimplementasikan sebagai skrip csh, yang dapat membaca konfigurasi yang mengubah PATH.
  • Ada builtin untuk itu. Dua, genap: typedan command. Cara POSIX:

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

    Di bash, Anda juga bisa menggunakan type -p emacsuntuk melihat lintasan dari perintah eksternal.

Namun, di sini, whichsebenarnya benar. Bash menyimpan informasi tentang lokasi perintah dalam memori, sehingga dapat menjalankan perintah lebih cepat di waktu berikutnya. Anda telah menginstal emacsexecutable baru pada Anda PATH, tetapi bash masih memiliki lokasi lama dalam cache-nya. Jalankan hash emacsuntuk mencari emacslagi, atau hash -runtuk mengosongkan cache.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1

Apakah Anda keluar dan masuk sehingga .bashrcfile login Anda yang diperbarui dibaca kembali? Jika tidak, lingkungan sesi Anda saat ini belum diperbarui.

JRFerguson
sumber
Jika itu masalahnya, `which emacs` --versionakan setuju dengan emacs --version, karena whichmewarisi PATH-nya dari shell saat ini.
mrb
@ Mrr: Poin diambil dengan baik.
JRFerguson