式またはコマンドを使用したフィルタの検索

式またはコマンドを使用したフィルタの検索

質問:

findシェル式で表されるすべての条件を満たすファイル(パス)セットを印刷するには、コマンドまたは代替方法を使用します。

前任者:ca.crtという証明書ファイルがあり、対応する組織単位(OU)はopenshiftです。次の式は、trueの場合はステータスコード0を返し、そうでない場合は0を返します。

openssl x509 -in ca.crt -text -noout 2>/dev/null | grep "OU = openshift" > /dev/null

findこの式とコマンドを使用して、指定されたディレクトリツリーで組織単位が「openshift」であるすべての証明書ファイルを見つけるにはどうすればよいですか。

私は見たことがない:

ページ-execのオプションは次のとおりです。findman

-exec command ;
              Execute command; true if 0 status is returned....

「状態0が返された場合はtrue」という特定のステートメントを理解していません。これはfind、特定のファイルに対するコマンド実行がゼロ状態を返すと、そのファイルが一致(true`)と見なされることを意味しますか?これは問題を解決するのに役立ちますか?

質問:

シェルスクリプトを書かずにこれを行う最も簡単な方法は何ですか?ライナーが理想的です。

答え1

ここでやりたいことは、in-execを含むパイプをfindテストとして使用することです。つまり、次のようになります。

find /search/path -type f -name ca.crt -exec something {} \; -print

パス名を印刷する必要がある場合は、終了somethingステータス0を返します。

これでパイプを直接使用することはできませんが、find次のように呼び出すことができますsh -c

find /search/path -type f -name ca.crt -exec sh -c '
    openssl x509 -in "$1" -text -noout 2>/dev/null |
    grep -F -q "OU=openshift"' sh {} \; -print

ここで何が起こるのかは、パイプラインを実行するためにfindインラインsh -cスクリプトが呼び出されることです(わずかに変更しました)。パイプがゼロ終了状態で終了すると(grep -q出力でテキストモードが見つかった場合に実行されますopenssl)、適用され、その-print名前ca.crtの一般ファイルのパス名が印刷されます。

ファイルのパス名はca.crtインラインスクリプトに渡されます$1


一般的に使用するほとんどの述語は次findのとおりです。テスト、含む-exec。テストラーメン渡す特定のパス名については、次のテストが考慮されます。

上記のコマンドでは、テストは「ファイルは通常のファイルですか?」() 、「-type f名前は何ですか?」ca.crt-name ca.crt)、「パス名を置き換えてこのコマンドを実行すると、終了ステータス{}は0になります。?」 (-exec ... \;)。最後は-printいつも本物-printしたがって、完了すると、それ以降の追加テストは常に完了します。


sh -c各パス名に対して一度ではなく、一度に多くのパス名に対してスクリプトを呼び出すと、少し効率的になります。次に、インラインスクリプトからパス名を印刷します。

find /search/path -type f -name ca.crt -exec sh -c '
    for pathname do
        if openssl x509 -in "$pathname" -text -noout 2>/dev/null |
            grep -F -q "OU=openshift"
        then
            printf "%s\n" "$pathname"
        fi
    done' sh {} +

のパス名を使用してループを正しく提供する方法ですfind

関連:

関連情報