質問:
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
のオプションは次のとおりです。find
man
-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
。
関連: