Linux 命令程序 查找顺序
我们使用echo $PATH查看如下:这是当前shell的PATH环境变量,
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/bin/chromedriver
我们使用env |grep PATH也能查看当前shell的PATH环境变量,
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/bin/chromedriver
我们知道在linux里面,一切皆文件,上面的PATH中显示的要么是目录(目录也是文件),要么是链接(连接也是文件),如下:
ls -al /usr/local/ |grep sbin
drwxr-xr-x 2 root root 4096 4月 20 2021 sbin
/usr/local/bin/ |grep chromedriver
lrwxrwxrwx 1 root root 29 1月 29 2022 chromedriver -> /usr/local/share/chromedriver
在当前shell里面执行python3, 当前shell会在当前shell的PATH中按照从左往右的顺序在目录中查找python3, 找了之后创建一个进程 运行python3的程序代码.
你可以创建一个文件 tt.py, 内容如下:
#!/usr/bin/python3 -u
import sys
import time
args = sys.argv
while True:
print(f"test transfer parameters: {args}")
time.sleep(2)
然后将tt.py文件通过sudo cp tt.py /usr/bin/tt.py命令,将其放到当前shell的PATH环境变量目录/usr/bin 下, 然后在shell中执行tt.py
calix@calix-Precision-5820-Tower:~/fzhu$ tt.py
test transfer parameters: ['/usr/bin/tt.py']
test transfer parameters: ['/usr/bin/tt.py']
^Z
[1]+ Stopped tt.py
calix@calix-Precision-5820-Tower:~/fzhu$ ps -ef |grep tt.py
calix 72479 72188 0 23:15 pts/2 00:00:00 /usr/bin/python3 -u /usr/bin/tt.py
calix 72481 72188 0 23:15 pts/2 00:00:00 grep --color=auto tt.py
calix@calix-Precision-5820-Tower:~/fzhu$
如果你复制一份tt.py的代码,然后将代码中的test transfer parameters修改为TEST TRANSFER PARAMETERS,
#!/usr/bin/python3 -u
import sys
import time
args = sys.argv
while True:
print(f"TEST TRANSFER PARAMETERS: {args}")
time.sleep(2)
然后将其拷贝一份放到/usr/sbin目录下( cp tt.py /usr/sbin/tt.py)
此时,在shell中执行tt.py, 会运行/usr/bin/ 下还是/usr/sbin下的tt.py文件呢?
因为在PATH环境变量中,/usr/sbin目录比/usr/bin目录要靠近左边, 所有优先在/usr/sbin目录中找tt.py
在shell中执行tt.py如下:
calix@calix-Precision-5820-Tower:~/fzhu$ tt.py
test transfer parameters: ['/usr/bin/tt.py']
test transfer parameters: ['/usr/bin/tt.py']
^CTraceback (most recent call last):
File "/usr/bin/tt.py", line 8, in <module>
time.sleep(2)
KeyboardInterrupt
为什么还是小写的test transfer parameters呢????
此时通过 whereis tt.py 和which tt.py来查看一下:
calix@calix-Precision-5820-Tower:~/fzhu$ whereis tt.py
tt: /usr/bin/tt.py /usr/sbin/tt.py
calix@calix-Precision-5820-Tower:~/fzhu$ which tt.py
/usr/sbin/tt.py
calix@calix-Precision-5820-Tower:~/fzhu$
没有问题啊, 为什么会这样呢? 是不是哪里设置了以/usr/bin为最优先查找tt.py的路径了呢?
如果是这样我们将/usr/bin下的tt.py删除了, 这样在/usr/bin 下找不到tt.py,就会去/usr/sbin下查找tt.py了吧.
赶紧将/usr/bin下的tt.py删掉, 删掉之后再看一下:
calix@calix-Precision-5820-Tower:~/fzhu$ whereis tt.py
tt: /usr/sbin/tt.py
calix@calix-Precision-5820-Tower:~/fzhu$ which tt.py
/usr/sbin/tt.py
calix@calix-Precision-5820-Tower:~/fzhu$
现在在shell里运行tt.py
calix@calix-Precision-5820-Tower:~/fzhu$ tt.py
-bash: /usr/bin/tt.py: No such file or directory
calix@calix-Precision-5820-Tower:~/fzhu$
为什么提示在/usr/bin 下找不到tt.py, 为什么还会在/usr/bin下找tt.py呢?
此时, 应该有什么想法, 明明tt.py 在/usr/bin 下被删除了, 不可能在/usr/bin下找到啊, PATH路径中这么多目录可以找,为什么一定要在/usr/bin这一个目录下找呢? 在/usr/bin目录下找不到,可以去其他目录中找啊, 此时就想到了bash查找应该有缓存机制, 在网上搜一下还真有.可以通过在当前shell中执行hash命令,查看到当前shell在其hash表里记住了哪些命令:
calix@calix-Precision-5820-Tower:~/fzhu$ hash
hits command
3 /usr/bin/mv
4 /usr/bin/python3
8 /usr/bin/which
1 /usr/bin/cp
12 /usr/bin/ls
3 /usr/bin/tt.py
5 /usr/bin/cat
3 /usr/bin/mkdir
9 /usr/bin/whereis
4 /usr/bin/sudo
calix@calix-Precision-5820-Tower:~/fzhu$
calix@calix-Precision-5820-Tower:~/fzhu$ hash --help
hash: hash [-lr] [-p pathname] [-dt] [name ...]
Remember or display program locations.
Determine and remember the full pathname of each command NAME. If
no arguments are given, information about remembered commands is displayed.
Options:
-d forget the remembered location of each NAME
-l display in a format that may be reused as input
-p pathname use PATHNAME as the full pathname of NAME
-r forget all remembered locations
-t print the remembered location of each NAME, preceding
each location with the corresponding NAME if multiple
NAMEs are given
Arguments:
NAME Each NAME is searched for in $PATH and added to the list
of remembered commands.
Exit Status:
Returns success unless NAME is not found or an invalid option is given.
calix@calix-Precision-5820-Tower:~/fzhu$
calix@calix-Precision-5820-Tower:~/fzhu$ hash -d tt.py
calix@calix-Precision-5820-Tower:~/fzhu$ hash
hits command
3 /usr/bin/mv
4 /usr/bin/python3
8 /usr/bin/which
1 /usr/bin/cp
12 /usr/bin/ls
5 /usr/bin/cat
3 /usr/bin/mkdir
9 /usr/bin/whereis
4 /usr/bin/sudo
calix@calix-Precision-5820-Tower:~/fzhu$
用hash -d tt.py 清除了当前shell的命令缓存hash表中的/usr/bin/tt.py 命令之后,继续执行tt.py如下:
calix@calix-Precision-5820-Tower:~/fzhu$ tt.py
TEST TRANSFER PARAMETERS: ['/usr/sbin/tt.py']
TEST TRANSFER PARAMETERS: ['/usr/sbin/tt.py']
^CTraceback (most recent call last):
File "/usr/sbin/tt.py", line 8, in <module>
time.sleep(2)
KeyboardInterrupt
calix@calix-Precision-5820-Tower:~/fzhu$
至此 shell的命令查找顺序我们总结为:
优先从shell的命令缓存hash表中查找, 找到之后按照绝对路径执行, 如果没有对应的命令,就去PATH目录中去找, 如果找到按照绝对路径执行,如果都没有找到则报错. Whereis 和which命令帮助确认文件在当前文件系统中的位置.