我正在编写一个快速脚本来列出目录中的所有文件,在每个文件上运行一个函数,然后打印出状态码。 现在我想要的状态码是整个事务,而不是最后执行的expression式。 例如…
find ./ -maxdepth 1 -name \*.txt -exec my_function {} \;
假设我的目录中有以下文件file1.txt
, file2.txt
, file3.txt
。 当file1.txt
被传递给-exec
它的状态码是1
但是调用file2.txt
和file3.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 {} \;