特定のファイルに対する操作が失敗した場合に中断するfind
ようにファイルを作成する方法はありますか?-exec
たとえば、javac
特定のファイルで他の理由なく終了コード1を返すことができるプログラムとして便利です。
$ echo "public classXX A{}" >> A.java
$ echo "public class B{}" >> B.java
$ find . -iname \*.java -exec javac {} \;
./A.java:1: error: class, interface, or enum expected
public classXX A{}
^
1 error
上記の例では、exec
ファイルがA.java
失敗して終了コード1を返しても、find
コマンドは続行してファイルをコンパイルしますB.java
。突破する方法はありますか?または、代わりにfind
どのフォームを使用する必要がありますか?for
私が見つけたバージョン:
$ find -version | head -1
find (GNU findutils) 4.4.2
答え1
私の考えでは...
find ... -exec sh -c 'cmd "$0" || kill $PPID' \{\} \;
...どの問題も解決する必要がありますfind
。
答え2
少なくともGNUの場合は、次のものをfind
使用できます。
find ... -exec ... -o -quit
答え3
マニュアルを参照してくださいfind
。 @Haukeの答えは私がそれを見つけるようにインスピレーションを与えました。 QNXの発見には-abort
GNUオプションに-quit
似たオプションがあります。私が使用し\(
て\)
表現をグループ化すると、私に効果的です。
find . -mtime -4 -name <pattern> \( -exec my_cmd {} \; -o -abort \)
注:角かっこがない場合は、最初のファイルで中断されます。
答え4
find --version
find (GNU findutils) 4.6.0
find . -name '*' \( -exec bash -c 'echo "$0" ; true' {} \; -o -quit \)
現在のディレクトリのすべてを一覧表示します
find . -name '*' \( -exec bash -c 'echo "$0" ; false' {} \; -o -quit \)
見つかった最初の項目(.)を一覧表示して停止します。
ここにあるパスで実行されるコマンドは次のとおりです。
echo "$0" ; true # echoes path and succeeds / returns true
そして
echo "$0" ; false # echoes path and fails / returns false
findと評価された式は次のとおりです。
-exec bash -c 'echo "$0" ; true/false' {} \;
そして
-quit
-oは論理OR(段落)です。
\(および\)が必要なので、シェルは検索するすべてを渡す前に項目を評価しようとしません。
find . -name '*' '(' -exec bash -c 'echo "$0" ; true' {} \; -o -quit ')'
そして
find . -name '*' '(' -exec bash -c 'echo "$0" ; false' {} \; -o -quit ')'
上記の \(\) バージョンと同じ結果を提供します。
findは ""をexprが初めて失敗したときにプロセス全体が停止することを意味する( <expression> -o -quit )
と解釈します。(expr || stop)
気づく 失敗した終了コードを find 呼び出し元に戻す方法はないようです。これにより、関数(-exec {}など)がスクリプトの目的でほとんど役に立たなくなります。