linux系统下有一个hash表,系统初始hash表为空,当外部命令执行时,默认会从PATH路径下寻找该命令,找到后会将这条命令的路径记录到hash表中,当再次使用该命令时,shell解释器首先会查看hash表,
存在将执行之,如果不存在,将会去PATH路径下寻找,利用hash缓存表可大大提高命令的调用速率。
hash命令是bash的内置命令,linux系统下每个shell都会有一个独立的hash表,当你新开一个shell的时候,这个hash表为空,每当你执行过一条命令时,hash表会记录下这条命令的路径,就相当于缓存一样。
hash就是用于记住命令的路径,并且在下次执行命令的时候直接通过hash获取而不再通过PATH一步步寻找,加快了寻找命令的速度。
hash命令是bash的内置命令。
hash 显示hash缓存
hash –l 显示hash缓存,加参数-l既可以看到hash表命令的路径,也可以看到它的名字,说不定会有别名
hash –p path name 将命令全路径path起别名为name
hash –t name 显示指定命令的完整路径
hash –d name 清除name缓存
hash –r 清除缓存
hash 显示hash缓存(hash表会记录下执行该命令的次数,以及命令的绝对路径)
# hash
hits command
1 /usr/bin/mesg
hash –r 清除缓存
[root@dev workspace]# hash
hits command
1 /usr/bin/mesg
[root@dev workspace]# hash -r
[root@dev workspace]# hash
hash: hash table empty
[root@dev workspace]#
将命令全路径path起别名,添加hash表,可以看到我把ls命令重新写了一遍,改名为bb,当我执行bb时就是执行ls命令
hash -p /usr/bin/ls bb
hash table搜索先于$PATH. hash table记录了最近的搜索路径。
问题描述:
如果之前调用了命令, 保存了搜索路径, 又改了环境变量, 按理说前面那个命令的搜索路径应该被更新, 由于hash table的存在, 就得不到更新.
网上举例:
我装了两个编译器, LLVM和GCC, 默认是GCC, 发现有代码只能用clang编译(既然发现了这一点, 说明我调用了GCC的gcc), 然后我改环境路径, 改完了用which gcc看, 是clang, 但执行的时候, 还是GCC. 就是这个原因。
这个场景其实很常见,意思就是,我们修改环境变量之前,执行过命令,命令会缓存在hash缓存中。我们修改了环境变量到新的命令中,但是执行的命令还是老命令,即使我们使用which查看没有问题,是已经修改过来了。
为什么呢?
就是因为hash table搜索先于$PATH, hash table没有被更新。
解决方案:
用hash -r清空hash table