La command Find renvoie des résultats différents lorsque -print0 est ajouté

Lorsque vous effectuez une search comme find -type d , l'ajout de l'argument -print0 juste après la command find telle que find -print0 -type d provoque la search de résultats plus que sans résultat.

Si vous comprenez les && et || opérateurs dans le shell (et aussi en C, C ++, et les langues dérivées), alors vous comprenez -a et -o dans find .

Pour rafraîchir votre memory:

Dans la coquille,

  command1 && command2 

exécute la command1 et, si elle ( command1 ) réussit, elle (le shell) exécute la command2 .

  command1 ||  command2 

exécute la command1 et, si elle échoue ( command1 ), elle (le shell) exécute la command2 .

Dans les langues compilables,

  expr1 && expr2 

évalue expr1 . Si elle ( expr1 ) évalue false (zéro), elle renvoie la valeur de l'expression globale. Sinon (si expr1 évalue à une valeur vraie (non nulle)), il évalue expr2 et renvoie cette valeur comme valeur de l'expression globale.

  expr1 ||  expr2 

évalue expr1 . Si elle ( expr1 ) évalue une valeur vraie (non nulle), elle renvoie la valeur de l'expression globale. Sinon (si expr1 évalue false (zéro)), il évalue expr2 et renvoie cette valeur comme valeur de l'expression globale.

    C'est ce que l'on appelle l'évaluation en court-circuit, car elle permet d'évaluer une expression booleanne sans évaluer les termes dont les valeurs ne sont pas nécessaires pour déterminer la valeur globale de l'expression.

Citant de find (1) ,

GNU find search l'arborescence des directorys enracinée à chaque nom de file en évaluant l'expression donnée de gauche à droite, selon les règles de préséance (voir section OPERATORS), jusqu'à ce que le résultat soit connu (le côté gauche est faux et les opérations, true pour ou ), à quel point la find passe au prochain nom de file.

EXPRESSIONS

L'expression est composée de … tests (qui renvoient une valeur vraie ou fausse), et d'actions (qui ont des effets secondaires et returnnent une valeur vraie ou fausse), séparés par des opérateurs. -et est supposé là où l'opérateur est omis.

    La sous-section sur ACTIONS stipule que -print , comme
    la plupart des actions, renvoie toujours la valeur true.

LES OPÉRATEURS


expr1 expr2
expr1 -a expr2
expr1 et expr2 ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ Non compatible POSIX

    Et; expr2 n'est pas évalué si expr1 est faux.

expr1 -o expr2
expr1 ou expr2 ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ Non compatible POSIX

    Ou; expr2 n'est pas évalué si expr1 est vrai.

La spécification Open Group pour find a des choses similaires à dire:

L'utilitaire find doit redescendre récursivement la hiérarchie des directorys …, en évaluant une expression booleanne composée des primitives décrites dans la section OPERANDS pour chaque file rencontré.

OPERANDS


-printing

    Le primaire doit toujours évaluer comme vrai; il doit faire en sorte que le path actuel soit écrit sur la sortie standard.


Les primaires peuvent être combinées en utilisant les opérateurs suivants (par ordre décroissant de priorité):

expression [-a] expression

    Conjonction des primaires; l'opérateur AND est impliqué par la juxtaposition de deux primitives ou rendu explicite par l'opérateur facultatif -a . La deuxième expression ne doit pas être évaluée si la première expression est fausse.

expression -o expression

    Alternance des primaires; l'opérateur OR. La deuxième expression ne doit pas être évaluée si la première expression est vraie.

Les deux documents disent: "Si aucune expression n'est présente, -print doit être utilisé comme expression".

—————- TL; DR —————-

Alors,

 find -type d 

est équivalent à

 find -type d -print 

ce qui équivaut à

 find -type d -a -print 

ce qui signifie,

  • pour chaque file,
    • évaluer le test de -type d .
    • Si c'est vrai (c'est-à-dire si le file actuel est un directory), évaluez (effectuez) l'action -print .

Attendu que ,

 find -print -type d 

est équivalent à

 find -print -a -type d 

ce qui signifie,

  • pour chaque file,
    • évaluer (effectuer) l'action -print (c'est-à-dire que cela se produit pour tous les files ) .
    • Si c'est vrai (lequel est toujours -print ), évaluez le test de -type d .
    • Et puisque c'est la fin de la command, le résultat du test -type d est ignoré.

Donc, vous l'avez.

L'ordre des arguments de search est important. La command doit être construite comme find -type d -print0 et ensuite elle fonctionnera comme prévu. Je pensais juste que je l'afficherais au cas où cela serait utile à qui que ce soit.

L'astuce pour comprendre une command find est d'évaluer récursivement et de regrouper les deux premières expressions / actions dans l'expression appropriée ( -false ou -false ) de la valeur logique résultante, en considérant que l'évaluation de chaque paire d'expressions / actions est court-circuitée donc les expressions / actions en tant que second opérande d'une comparaison AND ne seront pas évaluées et exécutées si la première expression évaluée est FALSE et que les expressions / actions en tant que second opérande d'une comparaison OR ne seront pas évaluées et exécutées si le premier l'expression évaluée est TRUE ) et que chaque action rencontrée au cours du process sera toujours évaluée comme TRUE et exécutée au moment de son évaluation (si elle n'est pas ignorée par une évaluation de court-circuit) en fonction de la valeur logique de l'évaluation précédente le moment de l'évaluation déjà réduit à une expression -false ou -false ) paire d'expressions / actions .

Élargir un exemple dans le lien utile posté par 1_CR:

 find . -false -o -false -a -printf 'nope\n' -o -printf 'yep\n' -o -printf 'nope\n' yep 
  • -false -o -false : le premier opérande est une expression, donc aucune action n'est exécutée, et sa valeur est FALSE ; l'évaluation n'est pas court-circuitée, puisque <expr1> est FALSE , donc -false est évalué et sa valeur est FALSE ; la valeur de l'expression entière est FALSE , et est réduite à une expression -false qui sera évaluée avec l'expression / action suivante;
  • -false -a -printf 'nope\n' : le premier opérande est une expression, donc aucune action n'est exécutée, et sa valeur est FALSE ; l'évaluation est court-circuitée, puisque <expr1> est FALSE , donc <expr2> n'est pas évalué et n'est pas exécuté; la valeur de l'expression entière est FALSE , et est réduite à une expression -false qui sera évaluée avec l'expression / action suivante;
  • -false -o -printf 'yep\n' : le premier opérande est une expression, donc aucune action n'est exécutée, et sa valeur est FALSE ; l'évaluation n'est pas en court-circuit, puisque <expr1> est FALSE , donc printf 'yep\n' est évalué et exécuté maintenant , et sa valeur est TRUE ; la valeur de l'expression entière est TRUE , et est réduite à une expression -true qui sera évaluée avec l'expression / action suivante;
  • -true -o -printf 'nope\n' : le premier opérande est une expression, donc aucune action n'est exécutée, et sa valeur est TRUE ; l'évaluation est court-circuitée, puisque <expr1> est TRUE , donc <expr2> n'est pas évalué et n'est pas exécuté; la valeur de l'expression entière est TRUE ;

find [...] -print0 -a -type d (car un opérateur manquant se développe en un opérateur AND ):

  • -print0 -a -type d : le premier opérande est une action, donc -print0 est évalué et exécuté maintenant , et sa valeur est TRUE ; l'évaluation n'est pas court-circuitée, puisque <expr1> est TRUE , le -type d est évalué et sa valeur est TRUE ou FALSE ; la valeur de l'expression entière est TRUE ou FALSE fonction du résultat du test de -type d ;