有时,在旧的 Linux 系统上,我遇到find
不支持-writable
和-readable
测试的情况,即测试文件或目录是否可写/可读。对于当前用户。
说,我要表达-writable
; then-perm -0002
不会是等价的,因为它不会通过所有者/组来测试用户是否具有写入权限。
我如何通过其他测试来表达find
的测试(例如)?-writable
find
-perm
答案1
没有什么方便的办法。这就是GNU 寻找添加-readable
和朋友的原因。
您可以通过枚举用户所在的组来构建一个近似权限测试的表达式。未经测试。
can_access="( -user $(id -u) -perm -0${oct}00 -o ("
for g in $(id -G); do
can_access="$can_access -group $g -o"
done
can_access="${can_access% -o} ) -perm -00${oct}0 -o -perm -000${oct} )"
find … $can_access -print
在某些情况下,这不会给出正确的结果,例如,如果存在访问控制列表,或者在边缘情况下,例如-rw----r--
拒绝对组的访问。您可以使用与上述相同的技术检查边缘情况,但表达式会变得更加复杂。对于访问控制列表,您需要调用支持它们的工具。
Perl 和 Python 等语言可以轻松访问access(2)
.find
在 Perl 中,与File::Find
和-r
//-w
-x
(使用 Perl 进程的有效 uid 和 gid — 使用//-R
来检查真实的 uid/gid ,并使用-W
-X
access(2)
filetest 'access'
杂注如果你的 Perl 不是太古老而不能支持 ACL 之类的东西):
use File::Find;
use filetest 'access';
find(sub { if (-r $_) { print "$_ is readable\n"; } }, '.');
在Python中,用os.walk
和os.access
(它使用Python进程的真实uid和gid,例如access(2)
):
import os
for dirpath, dirnames, filenames in os.walk('.', ):
for filename in filenames:
filename = os.path.join(dirpath, filenames)
if os.access(filename, os.R_OK):
print(filename + ' is readable\n')
唯一完全可靠的方法是尝试打开该文件。这需要外部实用程序,因此会比较慢。要测试常规文件的可读性:
find … -exec sh -c 'exec 2>/dev/null; : <"$0"' {} \; …
要测试可写性,请使用: >>"$0"
(这会打开文件进行追加,因此如果文件不可写,则会失败,但它实际上不会修改任何内容,特别是不会更新修改时间)。要测试目录的可读性,请使用ls -- "$0" >/dev/null
.要测试目录的可执行性,请使用cd -- "$0"
.对于常规文件的可执行性、目录的可写性或对大多数非常规文件的访问,没有被动测试。