DC娱乐网

用了这么久 Linux,才知道这些概念 Linux命令为啥敲个ls就能跑,明明它

用了这么久 Linux,才知道这些概念
Linux命令为啥敲个ls就能跑,明明它只在/usr/bin里。
这事其实挺简单,但掰开看,全是设计上的小心思。
你随便进个目录,比如/tmp或者/home,输ls,回车,它就出来了。
没报错,没提示找不到,连路径都不用写。
可ls这个文件,它真就老老实实躺在/usr/bin/ls或者/bin/ls里,哪也没挪过。
这背后不是运气,是三层东西卡得死死的。
第一层是PATH,一个环境变量,里头写着“只准从这几个地方找命令”。
它不叫搜索路径,它叫白名单——没写进去的目录,哪怕放了ls,shell也当它不存在。
你打开终端,输入echo $PATH,大概率会看到/bin:/usr/bin:/usr/local/bin这样的串。
顺序很重要,排前面的先找,找到了就不往后看了。
所以有人export PATH="/tmp:$PATH",结果一输ls,执行的可能是/tmp底下别人放的假ls。
这不是bug,是PATH本来就这么设计的:信任谁,全看顺序。
第二层是FHS,也就是文件系统分级标准。
它规定了/bin必须有ls,/usr/bin得放普通用户用的命令,/sbin放系统管理命令。
没有这个规矩,早年各家Unix自己乱建目录,/opt/bin、/usr/newbin、/local/bin全来一遍,PATH就成天改来改去。
现在不管Ubuntu还是CentOS,你ls /bin,里头一定有ls、cp、mv这些基础货。
不是巧合,是FHS硬性要求。
第三层是权限和执行上下文。
PATH找到ls,只是第一步。
接下来内核得查:这文件真有执行权限吗?当前用户有资格跑它吗?
比如普通用户输/sbin/ip,多半报“command not found”——不对,其实是“Permission denied”,因为权限不够。
再比如ping命令,它没设suid,但靠cap_net_raw能力也能发包,这是现代Linux给PATH加的安全补丁。
PATH不是万能钥匙,它只是一个引路人。
引到门口,还得刷脸、验指纹、看门禁卡,少一样都不让进。
开机时,systemd起来,读/etc/passwd知道该给你配啥shell,再加载/etc/profile和~/.bashrc,把PATH一层层拼出来。
你在Docker里跑容器,它默认PATH和主机差不多,不是巧合,是刻意照着FHS最小结构复制的。
chroot要是只挂了/,没挂/usr/bin,那你PATH再全也没用,execve直接返回“No such file or directory”。
排查PATH问题,别光echo $PATH。
先type ls,看看是不是被alias劫持了;
再command -v ls,看它到底从哪调的;
真卡壳了,strace -e trace=execve bash -c 'ls',看内核调用里它找的是不是你以为的那个路径;
最后ls -l和getcap一起敲,确认权限和能力没被悄悄改掉。
安全上最简单的动作:别让PATH里带点号。
也就是别写".:/usr/bin",否则当前目录有个恶意ls,你一输就中招。
CI脚本里更得写死路径,比如/usr/bin/curl,别信PATH——你不知道那个构建镜像PATH被谁动过。
PATH看起来是个小变量,其实它连着三根线:
一根连着FHS规范,一根连着内核execve校验,一根连着用户权限模型。
它让所有Linux发行版长得不一样,但用起来又几乎一样。
你能把树莓派上写的脚本,原封不动扔进云服务器跑,靠的就是这个。