我的“哪个”命令有时可能是错误的?


17

我已经从源代码(v24.2)编译了最新的emacs版本,因为我的计算机上安装的版本(v21.3)很旧。我已经照常做了:

$configure --prefix=$HOME
make 
make install

现在,我正在测试emacs,并意识到它仍会启动以前的版本...而我的$HOME/bin路径应该覆盖系统路径(因为它在我的.bashrc文件中位于$ PATH之前)。

我首先想到的是查看which命令输出。令人惊讶的是,它为新的emacs开辟了道路。我不明白这里的差异在哪里。在同一会话中,这里是不同的输出:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

我没有涉及emacs的别名。完全没有

$ alias | grep emacs
$

你知道发生了什么吗?


哪个emacs返回什么?
Ulrich Dangel 2012年

Answers:


29

我想到的三种可能性:

  • 存在别名emacs(已检查)
  • 存在一个功能 emacs
  • 新的emacs二进制文件不在您的Shell的PATH哈希表中。

您可以检查是否具有功能emacs

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

并将其删除:

unset -f emacs

您的外壳程序还有一个PATH哈希表,其中包含对PATH中每个二进制文件的引用。如果您在PATH中添加与现有二进制文件同名的新二进制文件,则需要通过更新哈希表来通知shell:

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中返回第一个,因为它不使用shell的哈希表。


1
尽管此处提供了很好的信息,但它会遗漏type命令。
jordanm 2012年

谢谢,我在使用sqlite3的新编译版本时遇到了同样的问题,这使我很生气(实际上确实返回了正确的路径,但shell没有调用正确的sqlite3 cli)。hash -r确实解决了我的问题。
mpm

12

是的,不要使用哪个

  • 在某些系统上,这是一个实现为csh脚本的外部命令,该命令可以读取更改的配置PATH
  • 有一个内置的。二,甚至:typecommand。POSIX方式:

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

    在bash中,您还可以type -p emacs用来仅查看外部命令的路径。

但是,这里which实际上是正确的。Bash将有关命令位置的信息保留在内存中,以便下次可以更快地执行命令。您已在上安装了新的emacs可执行文件PATH,但bash在其缓存中仍具有旧位置。运行hash emacsemacs再次查找,或hash -r清空缓存。


1

您是否注销并登录以导致.bashrc重新读取更新的登录文件?如果不是,则当前会话的环境尚未更新。


如果是这样,`which emacs` --version将与达成一致emacs --version,因为which它会从当前shell继承其PATH。
mrb 2012年

@mrb:点好。
JRFerguson 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.