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