我的“which”命令可能是错误的(有时)?

我的“which”命令可能是错误的(有时)?

我已经从源代码(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
$

知道发生了什么事吗?

答案1

我想到的三种可能性:

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

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

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

并删除它:

unset -f emacs

您的 shell 还有一个 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 的哈希表。

答案2

是的,不要使用哪个:

  • 在某些系统上,它是作为 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 emacs查找emacs,或者hash -r清空缓存。

答案3

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

相关内容