Esta es una limitación de find
. El POSIX standard especifica que el estado de devolución de find
es 0, a menos que se produzca un error al atravesar los directorios el estado de retorno de los comandos ejecutados no entra en él.
Puede hacer que los comandos escriban su estado en un archivo o en un descriptor:
find_status_file=$(mktemp findstatus)
: >"$find_status_file"
find … -exec sh -c 'trap "echo \$?" EXIT; invalid_command "$0"' {} \;
if [ -s "$find_status_file" ]; then
echo 1>&2 "An error occurred"
fi
rm -f "$find_status_file"
Otro método, a medida que descubierto , es utilizar xargs. Los comandos xargs
siempre procesan todos los archivos, pero devuelven el estado 1 si alguno de los comandos devuelve un estado distinto de cero.
find … -print0 | xargs -0 -n1 invalid_command
Otro método más es evitar find
y, en su lugar, utilizar globos recursivos en el shell: **/
significa cualquier profundidad de subdirectorios. Esto requiere la versión 4 o superior de bash; macOS está bloqueado en la versión 3.x, por lo que tendría que instalarlo desde una colección de puertos. Utilice set -e
para detener la secuencia de comandos en el primer comando que devuelve un estado distinto de cero.
shopt -s globstar
set -e
for x in **/*.xml; do invalid_command "$x"; done
Tenga en cuenta que en bash 4.0 a 4.2, esto funciona pero atraviesa enlaces simbólicos a directorios, lo que generalmente no es deseable.
Si usas zsh en lugar de bash, los globos recursivos funcionan fuera de la caja sin errores. Zsh está disponible por defecto en OSX / macOS. En zsh, solo puedes escribir
set -e
for x in **/*.xml; do invalid_command "$x"; done