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

yve*_*mes 19 bash emacs path which

我已经从源代码 (v24.2) 编译了最后一个 emacs 版本,因为我机器上安装的版本对我来说(v21.3)(相当)旧。我已经做了通常的:

$configure --prefix=$HOME
make 
make install
Run Code Online (Sandbox Code Playgroud)

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

我的第一个想法是查看which命令输出。令人惊讶的是,它为新的 emacs 提供了路径。我不明白这里的差异在哪里。在同一会话中,这里是不同的输出:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1
Run Code Online (Sandbox Code Playgroud)

我没有涉及 emacs 的别名。在所有。

$ alias | grep emacs
$
Run Code Online (Sandbox Code Playgroud)

知道发生了什么吗?

mrb*_*mrb 32

我想到的三种可能性:

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

你可以检查你是否有一个功能emacs

bash-3.2$ declare -F | fgrep emacs
declare -f emacs
Run Code Online (Sandbox Code Playgroud)

并删除它:

unset -f emacs
Run Code Online (Sandbox Code Playgroud)

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

hash -r
Run Code Online (Sandbox Code Playgroud)

补充说明:

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
Run Code Online (Sandbox Code Playgroud)

此脚本演示了新的二进制哈希表行为。

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
Run Code Online (Sandbox Code Playgroud)

虽然我没有调用它,which cat但总是会返回cat我的 PATH 中的第一个,因为它不使用 shell 的哈希表。


Gil*_*il' 12

是的,不要使用 which

  • 在某些系统上,它是作为 csh 脚本实现的外部命令,它可以读取更改PATH.
  • 有一个内置的。二,偶数:typecommand。POSIX方式:

    command -v emacs       # machine-readable format
    type emacs             # human-only format
    
    Run Code Online (Sandbox Code Playgroud)

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

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