Wons' Blog

个人博客

Android程序猿


回首向来萧瑟处,也无风雨也无晴

关于linux bash的缓存

在Linux下管理软件包时,经常会遇到莫名其妙的问题。 在Ubuntu下安装Scrapy时,第一次直接 apt-get install scrapy ,结果有些依赖问题,查询scrapy官网后,remove了Ubuntu自带源中的scrapy,重新从scrapy官网上下载package进行安装。结果运行的时候报错:

bash: /usr/local/bin/scrapy: No such file or directory

whereis 命令查找scrapy,发现在/usr/bin目录下。系统的PATH完全没有问题。

google很久之后才知道是bash的缓存的问题。

Linux中,更改存在于PATH目录中的程序位置之后,很可能会出现No such file or directory的错误提示。 比如在这里,第一次安装scrapy后,scrapy在PATH的/usr/local/bin目录下,remove之后重装,scrapy被安装到/usr/bin目录下,按照正常逻辑,此时直接执行scrapy的话,会找到/usr/bin/scrapy,因为/usr/bin也在环境变量PATH中,但却会出现bash: /usr/local/bin/python: No such file or directory 。

具体原因如下:

bash会保存执行时查找过PATH的程序的完整路径,这样下次就不需要再进行查找,如果在上次执行scrapy命令之后更改了scrapy的实际位置,则bash还会去按照原有hash table里面记录的路径去执行,但因为原执行文件已不存,所以会报出No such file or directory的错误提示。

通过执行 hash 命令可以查看bash缓存:

wliu@ubuntu:~$ hash
hits    command
   3    /usr/bin/which
   2    /usr/bin/file
   4    /usr/bin/sudo
   1    /bin/mv
   1    /usr/bin/whereis
   4    /usr/local/bin/scrapy
wsliu@ubuntu:~$

解决方法:

重置bash 的hash table即可,执行 hash -d scrapy 即可删除hash table中scrapy的记录,再次执行scrapy时,bash将搜索$PATH得到新的路径。

以下为Linux man page上的说明:

Bash uses a hash table to remember the full pathnames of executable files (see hash under SHELL BUILTIN COMMANDS below). A full search of the directories in PATH is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell searches for a defined shell function named command_not_found_handle. If that function exists, it is invoked with the original command and the original command’s arguments as its arguments, and the function’s exit status becomes the exit status of the shell. If that function is not defined, the shell prints an error message and returns an exit status of 127.

hash命令:

hash [-lr] [-p filename] [-dt] [name]

For each name, the full file name of the command is determined by searching the directories in $PATH and remembered. If the -p option is supplied, no path search is performed, and filename is used as the full file name of the command. The -r option causes the shell to forget all remembered locations. The -d option causes the shell to forget the remembered location of each name. If the -t option is supplied, the full pathname to which each name corresponds is printed. If multiple name arguments are supplied with -t, the name is printed before the hashed full pathname. The -l option causes output to be displayed in a format that may be reused as input. If no arguments are given, or if only -l is supplied, information about remembered commands is printed. The return status is true unless a name is not found or an invalid option is supplied.

最近的文章

Ubuntu下搭建PPTP VPN服务器

在Ubuntu Linux下搭建PPTP VPN服务器过程很简单。主要用到了pptpd程序。可以参照Ubuntu Community Help Wiki。1.设置PPTP服务器安装pptpdsudo apt-get install pptpd设置pptpdsudo vi /etc/pptpd.conf将服务器IP地址和客户端IP地址范围写到文件末尾。可以如下设置:localip 192.168.1.1remoteip 192.168.1.100-255设置DNS服务器sudo vi /et...…

Linux继续阅读
更早的文章

Windows7开机启动项管理

Windows7有很多种方式可以管理开机启动程序,这里介绍三种方式:管理“启动”目录,修改注册表,msconfig系统配置。1.“启动目录”Windows7下的系统“启动”目录中可以很方便地添加开机启动项,要添加时,只要向此目录里添加程序(或批处理文件)的快捷方式即可。如下:2.修改注册表可以在注册表路径HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run里添加或者删除启动项,如下:3.msconfig系统配置可以...…

Windows继续阅读