观察: 我有一个名为 foo 的可执行文件,位于 /b/foo 中。它是针对动态库的旧标头进行编译的,导致执行时出现段错误:
$ foo
Segmentation fault. // Expected behaviour.
现在,我根据新的动态库将 foo 的新版本编译到 /a/foo ,该库应该可以正常执行。目录 a/ 在我的 $PATH 中位于 b/ 之前,因此应选择 /a/foo:
$ which foo
/a/foo
当我执行 foo 时,会发生以下情况:
$ foo
Segmentation fault.
因此,似乎 /b/foo 被执行,而“which”告诉我 /a/foo 应该被执行。更奇怪的是,当我运行完整路径 $(which /a/foo) 时,一切运行正常:
$ /a/foo
OK!
$ cp /a/foo .
$ ./foo
OK!
更进一步,如果我现在删除 /a/foo:
$ rm /a/foo
那么一定要选择/b/foo,对吧?
$ which foo
/b/foo
$ foo
bash: /a/foo: No such file or directory
$ $(which foo)
Segmentation fault. // Expected result.
没有!
使固定: 源 .bash_profile 和 .bashrc 问题就消失了。
重现性: 每次。只需删除 /a/foo,source ~/.bash_profile,创建 /a/foo,就会再次出现上述观察结果。
问题: 有谁知道这里出了什么问题吗?
假设: “which”是最新的,但系统根据“过去的情况”进行选择。在上面的示例中,打开终端时 /a/foo 还不存在:我刚刚创建了它。因此,当创建 /a/foo 时,“which”确实检测到 /a/foo,但系统仍然选择 /b/foo,因为它不知何故不同步? 但为什么系统不同步呢?
答案1
Bash 缓存命令的位置。用于hash foo
强制它更新缓存。
另外,which
这是一个单独的命令,它不会告诉您 shell 实际在哪里查找;它只是查阅$PATH
环境变量。在 bash 中,您应该使用type
:
$ type foo
foo is hashed (/a/foo)