Dans cette démonstration, j'utiliserai sh -c 'echo first; false'
(ou true
) pour les premiers -exec
. Cela donnera une sortie et aura également l'effet de code de sortie sélectionné. Alors echo second
sera utilisé pour le second. Supposons qu'il y ait un fichier dans le répertoire courant.
$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
Une vraie commande de ce type ressemblerait à :
find . -type f \( -exec command1 \; -false -o -exec command2 \; \)
Dans le second ensemble, les parenthèses échappées regroupent les deux -exec
clauses. Le -false
entre eux force l'état du test à "faux" et le -o
provoque l'expression suivante (la seconde -exec
) à évaluer à cause du -false
.
À partir de man find
:
expr1 expr2
Deux expressions consécutives sont considérées comme jointes par un "et" implicite ; expr2 n'est pas évalué si expr1 est faux.expr1 -a expr2
Identique à expr1 expr2.expr1 -o expr2
Ou; expr2 n'est pas évalué si expr1 est vrai.
Si vous n'avez pas d'importance à ce que cmd1 puisse empêcher l'exécution de cmd2 en raison du code d'erreur 0
:
find . -exec cmd1 \; -exec cmd2 \;
Le seul moyen fiable d'obtenir que les deux commandes s'exécutent toujours est d'avoir find
invoquez un shell qui exécutera ensuite les commandes dans l'ordre :
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Si cela ne vous dérange pas de créer un script qui fait cmd1 et cmd2, alors c'est juste ça :
find . -exec myscript {} \;
ou
find . -exec myscript {} +
Utilisation \; ou + selon que monscript peut gérer plus d'un fichier à la fois (il devient poilu s'il y a des espaces dans les noms de fichiers, etc.).
Mettre ce que vous faisiez dans un script, d'après mon expérience, en a presque toujours valu la peine. Si vous devez le faire une fois, vous devrez le refaire.
Mais une astuce consiste à mettre la trouvaille à l'intérieur le scénario :
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Ensuite, myscript fonctionne sur tous les fichiers que vous donnez comme arguments pour qu'il fonctionne, mais si vous ne lui donnez aucun argument, il exécute find à partir du répertoire actuel, puis s'appelle sur les fichiers trouvés. Cela contourne le fait que find -exec ne peut pas appeler les fonctions shell que vous avez définies dans votre script.