Linux/bash 不执行“which”告诉我的可执行文件

Kev*_* As 2 linux bash path which

观察: 我有一个名为 foo 的可执行文件,位于 /b/foo 中。它是针对动态库的旧头文件编译的,导致它在执行时出现段错误:

$ foo
Segmentation fault. // Expected behaviour.
Run Code Online (Sandbox Code Playgroud)

现在,我针对新的动态库将新版本的 foo 编译到 /a/foo ,该库应该可以正常执行。目录 a/ 在 b/ 之前在我的 $PATH 中,因此应选择 /a/foo:

$ which foo
/a/foo
Run Code Online (Sandbox Code Playgroud)

当我执行 foo 时,会发生以下情况:

$ foo
Segmentation fault.
Run Code Online (Sandbox Code Playgroud)

因此,似乎 /b/foo 被执行了,而“which”告诉我 /a/foo 应该被执行。为了让事情变得更奇怪,当我运行完整路径 $(which /a/foo) 时,事情运行良好:

$ /a/foo
OK!

$ cp /a/foo .
$ ./foo
OK!
Run Code Online (Sandbox Code Playgroud)

再进一步,如果我现在删除 /a/foo:

$ rm /a/foo
Run Code Online (Sandbox Code Playgroud)

那么/b/foo肯定是选的吧?

$ which foo
/b/foo
$ foo
bash: /a/foo: No such file or directory
$ $(which foo)
Segmentation fault. // Expected result.
Run Code Online (Sandbox Code Playgroud)

不!

修复: 源 .bash_profile 和 .bashrc 问题消失。

再现性: 每次。删除/a/foo,source ~/.bash_profile,创建/a/foo,上面的观察又出现了。

问题: 有谁知道这里出了什么问题?

假设: “哪个”是最新的,但系统根据“过去是什么”进行选择。在我上面的例子中,当终端打开时 /a/foo 还不存在:我刚刚创建了它。因此,当创建/a/foo 时,“which”确实检测到/a/foo,但系统仍然选择/b/foo,因为它不知何故不同步? 但是为什么系统不同步?

Mar*_*eed 8

Bash 缓存命令的位置。使用hash foo迫使它更新缓存。

此外,which是一个单独的命令,它不会告诉您 shell 的实际位置;它只是咨询$PATH环境变量。在 bash 中,您应该使用type

$ type foo
foo is hashed (/a/foo)
Run Code Online (Sandbox Code Playgroud)