findテストとbashテストは同じ結果を提供しません。なぜですか?

findテストとbashテストは同じ結果を提供しません。なぜですか?

私の前の質問からfind -execで現在のファイルを{}に置き換える方法は?、テストについて問い合わせましたfind。私に属していないすべてのファイルを探したいです。したがって、正しいfindコマンドがあります。

find . -type f ! -user "$USER"

しかし、これは次のようになります。

find . -type f -exec bash -c '
    for pathname do
        [[ ! -O "$pathname" ]] && printf "%s\n" "$pathname"
    done' bash {} +

ただし、どちらも異なる結果を提供します。

1)これを行うと[command one] | wc -c- > 4121

しかし: [command two] | wc -c--> 236768 (PS: $HOME でファイルを検索しています。)

どちらも見つかったファイルの数が異なります。

2)両方とも結果ファイルを提供します。目次(はい、私はディレクトリを所有していないので権限が拒否されました。)find . -type fオプション引数に(ディレクトリの代わりに)ファイルタイプがあるのにディレクトリが提供されるのはなぜですか? (ls -ldディレクトリの1つに移動すると、リンクや何もありません。)

答え1

うーん...両方のコマンドは私のホームディレクトリで同じように動作します。 8-/

それにもかかわらず、stderrを/ dev / nullにリダイレクトし、wc -lそれを使用して出力を正しく計算する必要があります。

find . -type f ! -user "$USER" 2>/dev/null | wc -l
find . -type f -exec bash -c '
    for pathname do
        [[ ! -O "$pathname" ]] && printf "%s\n" "$pathname"
    done' 2>/dev/null bash {} + | wc -l

ここでは、結果をテキストファイルにリダイレクトし、ファイルを比較して違いを見つけることができます。

find . -type f ! -user "$USER" 2>/dev/null > /tmp/file_1.txt
find . -type f -exec bash -c '
    for pathname do
        [[ ! -O "$pathname" ]] && printf "%s\n" "$pathname"
    done' 2>/dev/null bash {} + >/tmp/file_2.txt
diff /tmp/file_{1,2}.txt

違いがある場合は、/tmp/file_2.txtのいくつかの追加ファイルを取り出して、そのファイルが「ファイルが存在し、有効なユーザーIDが所有している場合はTrue」と見なされない理由を詳しく調べてください。

答え2

find実際にアクセスできないディレクトリを入力したくない場合は、次のものを使用できます! -executable -prune

find . ! -executable -prune -type f ! -user "$USER"

-executableアクセス権がないディレクトリの場合、否定テストが維持され、そのディレクトリは-prune検索ツリーから削除され、findユーティリティがそのディレクトリにアクセスできなくなり、権限エラーの生成を防ぎます。

この-executableテスト(および同様の-readableテスト-writable)は非標準であり、GNUが必要ですfind

あなたはそれについて何も言わなかったので、結果の違いについて(まだ)コメントすることはできません。出力サイズが非常に多様であるため、あるコマンドが他のコマンドが見つからないものを見つける場合を見つけて確認することは容易ではありません。

関連情報