Ric*_*ich 11 permissions readonly test
如果我以非特权用户的身份创建一个文件,并将权限模式更改为400
,则该用户正确地将其视为只读:
$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro
Run Code Online (Sandbox Code Playgroud)
一切都很好。
但后来 root 出现了:
# [ -w somefile ] && echo rw || echo ro
rw
Run Code Online (Sandbox Code Playgroud)
有没有搞错?当然,root 可以写入只读文件,但它不应该养成这样的习惯:最佳实践往往会规定我应该能够测试写权限位,如果不是,则已设置那样是有原因的。
我想我想了解为什么会发生这种情况,以及在测试没有设置写入位的文件时如何获得错误的返回码?
Ste*_*ris 30
我想你误解了什么是什么-w
。它不会检查文件是否具有“写入权限”,而是检查文件是否可由调用用户写入。
更具体地说,它调用access(2)
或类似。
例如,如果一个脚本有if [ -w /etc/shadow ]
那么如果你strace
在脚本上运行你可能会看到类似于
faccessat(AT_FDCWD, "/etc/shadow", W_OK)
Run Code Online (Sandbox Code Playgroud)
由于root
可以写入文件,因此它返回 0。
例如作为普通用户:
faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)
Run Code Online (Sandbox Code Playgroud)
作为根
faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0
Run Code Online (Sandbox Code Playgroud)
这,尽管事实上在我的机器上/etc/shadow
有权限000
。
---------- 1 root root 4599 Jan 29 20:08 /etc/shadow
Run Code Online (Sandbox Code Playgroud)
现在你想做的事情变得有趣而不是那么简单。
如果您想检查简单的权限,请检查ls
输出,或调用stat
或类似的。但要意识到 ACL 可以覆盖这些权限。仅仅因为文件的权限为 400 并不能阻止它的可写性...
phe*_*mer 27
test -w
aka[ -w
不检查文件模式。它检查它是否可写。对于 root,它是。
$ help test | grep '\-w'
-w FILE True if the file is writable by you.
Run Code Online (Sandbox Code Playgroud)
我要测试的方法是对stat(1)
(“%a
八进制访问权限”)的输出进行按位比较。
(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro
Run Code Online (Sandbox Code Playgroud)
请注意,子shell$(...)
需要一个0
前缀,以便将 的输出stat
解释为八进制(( ... ))
。