`find` の -writable および -readable テストが利用できない場合、どのように表現すればよいでしょうか?

`find` の -writable および -readable テストが利用できない場合、どのように表現すればよいでしょうか?

古い Linux システムでは、ファイルまたはディレクトリが現在のユーザーに対して書き込み可能/読み取り可能かどうかをテストするテストがfindサポートされていないことが-writableあります。-readable

たとえば、-writable; を表現したい場合、-perm -0002これは、ユーザーが所有者/グループによって書き込み権限を持っているかどうかをテストしないため、同等ではありません。

findのテストを の他のテスト (例)-writableを使用して表現するにはどうすればよいですか?find-perm

答え1

便利な方法はありません。それが、GNU find が追加された理由です-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実際-W-Xuid/gidをチェックし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"。通常のファイルの実行可能性、ディレクトリの書き込み可能性、またはほとんどの非通常ファイルへのアクセスをテストする受動的なテストはありません。

関連情報