每个parameter passing给find中的-exec后的状态

我正在编写一个快速脚本来列出目录中的所有文件,在每个文件上运行一个函数,然后打印出状态码。 现在我想要的状态码是整个事务,而不是最后执行的expression式。 例如…

find ./ -maxdepth 1 -name \*.txt -exec my_function {} \; 

假设我的目录中有以下文件file1.txtfile2.txtfile3.txt 。 当file1.txt被传递给-exec它的状态码是1但是调用file2.txtfile3.txt返回0 。 当我调用echo $? 在最后它从最后一个expression式执行返回0 ,尽pipe调用file1.txt返回1 。 我想要的是一个非零的状态码,如果任何一个expression式在上面的脚本中返回一个非零值,就像file1.txt所描述的那样。 我会怎么做呢?

我会建议这样的事情:

 status=0 while IFS= read -d '' -r file; do my_function "$file" ((status |= $?)) done < <(find . -maxdepth 1 -name '*.txt' -print0) echo "status=$status" 

这将打印status=1如果任何存在的状态是从my_function 1

你可以做这样的事情(用GNU find进行测试),它将为每个文件打印出一个exec,并返回非零状态:

 find . -maxdepth 1 -name "*.txt" '(' -exec my_function {} \; -o -printf 1\\n ')' 

您可以使用-printf打印更多信息,如文件名。 但是在任何情况下,只有当my_function对某个文件失败时才会输出。 (或如果它打印的东西。)

 find . -maxdepth 1 -name \*.txt -print0 | xargs -r0 -I {} sh -c "echo {}; echo $?;" 

根据从lcd047收到的建议,为了避免名称中包含"问题,一个更好的解决方案是

 find . -maxdepth 1 -name \*.txt -print0 | xargs -r0 -I {} sh -c 'printf "%s\n" "$1"; echo $?' sh {} \; 

尽管-exec ... \; 只返回退出状态作为主要的真值, -exec ... {} +使find调用返回非零退出状态,如果任何调用返回非零退出状态(并始终返回true作为主,因为一个调用可能处理多个文件)。

如果my_function处理多个参数,那么

 find ./ -maxdepth 1 -name \*.txt -exec my_function {} \; 

会做这项工作。

如果没有,你可以做

 find ./ -maxdepth 1 -name \*.txt -exec sh -c 'r=0; for arg do my_function "$arg" || r=1; done; exit "$r"' sh {} \;