我对执行文件权限的行为不符合我的预期感到困惑。可能是因为我的期望是错误的。反正:
我有一个脚本文件,为简单起见,称为s
,位于~/bin
.就本示例而言,该文件仅包含以下行:
#!/bin/zsh
echo "Test";
很简单。
我导航到该~/bin
目录,并且chmod
文件权限为s
-400
即,仅供我只读。无执行权限。然后我尝试通过输入脚本的路径来执行脚本,给出以下内容:
% ./s
zsh: permission denied: ./s
到目前为止,一切都很好。由于权限错误,该文件无法执行。将权限提升到500
(授予执行权限)也可以正常工作 - 使用这些权限,文件可以正常执行:
% ./s
Test
这一切都在预料之中。但后来我的chmod
权限恢复到400
(再次执行权限关闭),尝试source
ing 该文件,并且发生这种情况:
% source s
Test
尽管权限为400
,但脚本仍会执行。
所以这是我的问题:为什么会./s
失败(就像它应该的那样)但source s
执行正常?这不是违背了执行权限的全部目的吗?
在400
权限下,sh s
也zsh s
可以工作。
我确信我在某个地方正在做或理解一些严重错误的事情。有人可以向我指出哪里,并解释./s
、source s
和之间的区别sh s
吗zsh s
?
答案1
当您运行时./s
,您告诉内核执行该程序s
。如果您具有执行权限,则内核会读取文件的前几个字节,看到该#!
行,因此它知道这是一个脚本,然后运行解释器,将脚本名称作为第一个参数传递给它。如果没有执行权限,内核会在第一步中止执行。
当您运行 时zsh s
,您执行zsh
,并告诉它读取调用的文件s
并将其解释为命令。你不是在执行s
,你是在执行zsh
。与sh s
或相同cat s
。
当您source s
再次运行时,您告诉 zsh 读取文件,因此重要的是您拥有该文件的读取权限。