公众号旧文
为什么 Linux 脚本前要加 ./ 而 Win 却不用?
前天,我写了一篇关于 PATH 环境变量的文章。
直到那时我才明确知道,系统执行命令时,并不会去整块硬盘里搜索。
而是只会在 PATH 里的目录中查找。
但刚刚我发现,还有一个问题:
在 Linux 里,即使程序就在当前目录,系统也不能直接执行它。
一、经典翻车现场
我的服务器里,当前目录下明明就有一个脚本:
server_check.sh

但当我直接输入:
server_check.sh
系统却提示:
-bash: server_check.sh: command not found

随后我在前面加上了 ./ :
./server_check.sh
脚本瞬间正常执行:

那么问题来了:
既然文件就在当前目录,为什么 Linux 却说 not found ?
二、Linux 根本没在当前目录里找
很多 Windows 用户刚接触 Linux 时,都会默认当前目录里的程序,系统能直接运行。
但 Linux 不是这么设计的。
Linux 在执行命令时,默认不会搜索当前目录。
也就是说当你输入:
server_check.sh
Linux 实际上只在 PATH 里的目录中寻找:
server_check.sh
而不是在你当前的这个目录里找。
如果 PATH 里没有,系统就会直接提示 not found
三、那 ./ 是什么意思,为什么加上就可以了?
这里的:
./
就是:
当前目录
所以:
./server_check.sh
就是:
执行“当前目录”里的 server_check.sh
也就是说,加上 ./ 就是在明确告诉 Linux:
别去 PATH 里找了,就在这里呢,执行吧。
四、这和 Windows 完全不一样
Windows 用户之所以容易困惑,是因为 Windows 的行为逻辑不同。
比如我当前目录有:
php.exe

那么直接输入:
php
Windows 就能运行:

因为 Windows 会:
- 搜索当前目录
- 搜索 PATH
- 自动补 .exe 扩展名
五、为什么 Linux 要这样设计?
假设 Linux 默认也搜索当前目录。
那么会发生什么?
比如你进入了一个陌生目录,里面有人偷偷放了一个恶意脚本 ls
这时候你输入
ls
本来你以为运行的是真正的:
/bin/ls
结果实际上执行的,却是当前目录里的假 ls
那就危险了。
所以 Linux 的设计理念是当前目录默认不可信。
除非你明确写:
./ls
否则系统不会执行当前目录里的程序。
六、最后的总结
Windows:
当前目录 + PATH + 自动补扩展名
Linux:
只查 PATH
不搜当前目录
不补扩展名
Windows 倾向于替用户猜,而 Linux 倾向于要求用户明确表达。