Files

find 的 -writable 和 -readable 測試不可用時,如何表達它們?

  • June 1, 2019

有時在舊的 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 like access(2),如果您的 Perl 不是太古老而無法支持,請使用filetest 'access'pragma ACL 之類的東西):

use File::Find;
use filetest 'access';
find(sub { if (-r $_) { print "$_ is readable\n"; } }, '.');

在 Python 中,with os.walkand 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". 對於正常文件的可執行性、目錄的可寫性或對大多數非正常文件的訪問,沒有被動測試。

引用自:https://unix.stackexchange.com/questions/522364