J'essaie d'exécuter des commandes multiples sur des éléments que j'ai trouvés, comment puis-je y parvenir ?
find . -exec cmd1; cmd2
ne semble pas fonctionner ; il exécute plutôt cmd2 après que cmd1 ait été exécuté sur chaque fichier.
J'essaie d'exécuter des commandes multiples sur des éléments que j'ai trouvés, comment puis-je y parvenir ?
find . -exec cmd1; cmd2
ne semble pas fonctionner ; il exécute plutôt cmd2 après que cmd1 ait été exécuté sur chaque fichier.
Dans cette démonstration, je vais utiliser sh -c 'echo first; false'
(ou true
) pour le premier -exec
. Cela donnera une certaine sortie et aura également l'effet du code de sortie sélectionné. Puis 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 à ceci :
find . -type f \( -exec command1 \; -false -o -exec command2 \; \)
Dans le deuxième ensemble, les parenthèses échappées regroupent les deux -exec
clauses. Le site -false
entre eux force l'état du test à "false" et la -o
entraîne l'expression suivante (la deuxième -exec
) à évaluer en raison de la -false
.
De man find
:
expr1 expr2
Deux expressions dans une rangée sont considérées comme jointes par un sous-entendu. "et" implicite ; expr2 n'est pas évaluée si expr1 est fausse.expr1 -a expr2
Identique à expr1 expr2.expr1 -o expr2
Ou ; expr2 n'est pas évalué si expr1 est vrai.
Si vous ne vous souciez pas que cmd1 puisse empêcher cmd2 d'être exécuté à cause du code d'erreur 0
:
find . -exec cmd1 \; -exec cmd2 \;
La seule façon fiable d'obtenir que les deux commandes s'exécutent toujours ainsi est d'avoir find
invoque un Shell qui exécutera ensuite les commandes en séquence :
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Si ça ne vous dérange pas de faire un script qui fait cmd1 et cmd2, alors c'est juste ça :
find . -exec myscript {} \;
o
find . -exec myscript {} +
Utilisez \ ; ou + selon que myscript peut ou non gérer plus d'un fichier à la fois (cela devient délicat s'il y a des espaces dans les noms de fichiers, etc).
Mettre ce que vous faisiez dans un script, dans mon expérience, a presque toujours valu la peine. Si vous devez le faire une fois, vous devrez le faire à nouveau.
Mais une astuce astucieuse consiste à mettre la trouvaille à l'intérieur de le script :
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Ensuite, myscript travaille sur les fichiers que vous lui donnez comme arguments, mais si vous ne lui donnez pas d'arguments, il lance find à partir du répertoire courant, et s'appelle lui-même sur les fichiers trouvés. Ceci contourne le fait que find -exec ne peut pas appeler les fonctions Shell que vous avez définies dans votre Shell.
SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.