有没有一种方法可以编写一个文件,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
on the fileA.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
至少对于 GNUfind
你可以使用:
find ... -exec ... -o -quit
答案3
请参阅您的find
手册。 @Hauke 的回答激励我去寻找,QNX 的 find 有一个-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 是逻辑或(短路)
您需要 \( 和 \),因此 shell 在传递所有内容进行查找之前不会尝试评估内容:
find . -name '*' '(' -exec bash -c 'echo "$0" ; true' {} \; -o -quit ')'
和
find . -name '*' '(' -exec bash -c 'echo "$0" ; false' {} \; -o -quit ')'
给出与上面的 \( \) 版本相同的结果。
find 将“ ( <expression> -o -quit )
”解释为(expr || stop)
第一次 expr 失败时整个过程停止。
注意 似乎没有任何方法可以将失败的退出代码传递回 find 的调用者,这使得功能(-exec {} 等)对于脚本编写而言几乎无用。