當 find
的 -writable 和 -readable 測試不可用時,如何表達它們?
有時在舊的 Linux 系統上,我遇到
find
不支持-writable
和-readable
測試的情況,它們分別測試文件或目錄是否可寫/可讀。對於目前使用者。說,我要表達
-writable
;then-perm -0002
將不等效,因為它不會通過所有者/組來測試使用者是否具有寫權限。如何通過’ 的其他測試(例如)來表達
find
’ 的測試?-writable``find``-perm
沒有什麼方便的方法。這就是為什麼 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 中,withFile::Find
和-r
/-w
/-x
(使用 Perl 程序的有效 uid 和 gid — 使用-R
/-W
/-X
來檢查真正的 uid/gid likeaccess(2)
,如果您的 Perl 不是太古老而無法支持,請使用filetest 'access'
pragma ACL 之類的東西):use File::Find; use filetest 'access'; find(sub { if (-r $_) { print "$_ is readable\n"; } }, '.');
在 Python 中,with
os.walk
andos.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"
. 對於正常文件的可執行性、目錄的可寫性或對大多數非正常文件的訪問,沒有被動測試。