読み取り権限のみを持つディレクトリ内のファイルに対してテスト -e が失敗するのはなぜですか?

読み取り権限のみを持つディレクトリ内のファイルに対してテスト -e が失敗するのはなぜですか?

ディレクトリの読み取り権限について私が理解したところによれば、ディレクトリ内のファイルだけが一覧表示され、それ以上は許可されません。

次の所有する0744権限を持つディレクトリが提供されますuserA

[userA@localhost ~]$ mkdir -m 0744 /tmp/semi-secret
[userA@localhost ~]$ ls -ld /tmp/semi-secret/
drwxr--r--. 2 userA userA 6 Aug 29 10:15 /tmp/semi-secret/
[userA@localhost tmp]$ touch semi-secret/foobar.txt
[userA@localhost tmp]$ chmod 0600 semi-secret/foobar.txt

userBで、ファイルの存在はコマンドを通して知ることができます。foobar.txtls

[userB@localhost ~]$ ls -l /tmp/semi-secret/
ls: cannot access /tmp/semi-secret/foobar.txt: Permission denied
total 0
-????????? ? ? ? ?            ? foobar.txt

しかし、test -eコマンドがゼロ以外の状態で終了するのはなぜですか? !唯一の作業は、ファイルが存在すること、およびディレクトリ権限がそれを許可することを確認することです。

[userB@localhost ~]$ test -e /tmp/semi-secret/foobar.txt || echo "The file doesn't exist."
The file doesn't exist.

答え1

許可ビットがないディレクトリのファイルではシステムコールもstat(2)機能できないため、これらのディレクトリではシステムコールに基づくすべての操作が失敗します。xstat(2)

ディレクトリに対応するrビットが設定されている場合、実際にはそのディレクトリの内容を読み取ることができますが、ファイルはreaddir()読み取れません。statopen

x逆に、このビットが設定されているディレクトリを使用すると、問題のファイル名を知っていても問題のディレクトリの内容を取得できない場合は、ファイルを検索できますstat(2)openreaddir()

test -eファイルが存在しない場合(シンボリックリンクの確認後も適用されます)、ゼロ以外の状態で終了します。既存のシンボリックリンク存在しないまたはアクセスできないファイル)またはstat(2)関連ファイルへのアクセス中にエラーが発生しました。

答え2

@schilyの良い答えを補うために読み取りアクセス権がありますが、必ずしも特定のディレクトリに対するものではないことを確認する方法です。探す特定の名前を含むエントリにアクセスするには、そのディレクトリの内容を読み、ファイル名を見つけます。

これを達成するためにシェルワイルドカードを使用できます。

set -- /tmp/semi-secret/[f]oobar.txt
if [ "$1" = /tmp/semi-secret/foobar.txt ]; then
  echo exists
fi

を使用すると、zsh次の操作も実行できます。

if ()(($#)) /tmp/semi-secret/foobar.txt(N); then
  echo exists
fi

findサポートされる実装を通じて-maxdepth:

if find /tmp/semi-secret -mindepth 1 -maxdepth 1 -name foobar.txt -print |
     grep -q '^'; then
  echo exists
fi

ソリューションを除いて、zsh任意のファイル名に適応することは困難です。

関連情報