Il s'agit d'une limitation de find
. Le site Norme POSIX spécifie que le statut de retour de find
vaut 0 sauf si une erreur s'est produite lors du parcours des répertoires ; le statut de retour des commandes exécutées n'entre pas en ligne de compte.
Vous pouvez faire en sorte que les commandes écrivent leur état dans un fichier ou dans un descripteur :
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"
Une autre méthode, comme vous l'avez découvert est d'utiliser xargs. Le site xargs
traite toujours tous les fichiers, mais renvoie le statut 1 si l'une des commandes renvoie un statut non nul.
find … -print0 | xargs -0 -n1 invalid_command
Une autre méthode consiste à éviter find
et utiliser le globbing récursif dans le shell à la place : **/
signifie une profondeur quelconque de sous-répertoires. Cela nécessite la version 4 ou supérieure de bash ; MacOS est bloqué à la version 3.x, vous devrez donc l'installer à partir d'un catalogue de logiciels portés. Utilisez set -e
pour arrêter le script à la première commande retournant un état non nul.
shopt -s globstar
set -e
for x in **/*.xml; do invalid_command "$x"; done
Attention, dans bash 4.0 à 4.2, cela fonctionne mais traverse des liens symboliques vers des répertoires, ce qui n'est généralement pas souhaitable.
Si vous utilisez zsh au lieu de bash, le globbing récursif fonctionne sans problème. Zsh est disponible par défaut sur OSX/MacOS. Dans zsh, vous pouvez simplement écrire
set -e
for x in **/*.xml; do invalid_command "$x"; done
0 votes
stackoverflow.com/questions/14871147/