128 votes

Recherche de fichiers exécutables à l'aide de la commande find

Quel type de paramètre/flag puis-je utiliser avec l'option Unix find pour que je recherche les exécutables ?

0 votes

Tapez 'man find'. Je pense que l'option '-executable' est celle que vous voulez.

3 votes

find -executable ... mais cela ne garantit pas que tous les fichiers listés s'exécutent réellement.

1 votes

Toutes les implémentations de find sont créés égaux. L'option recommandée par @sje397 et @William peut ne pas être disponible. Il est préférable d'utiliser le solution acceptée montré ci-dessous.

199voto

Laurence Gonsalves Points 50783

Sur les versions GNU de find, vous pouvez utiliser -executable :

find . -type f -executable -print

Pour les versions BSD de find, vous pouvez utiliser -perm avec + et un masque octal :

find . -type f -perm +111 -print

Dans ce contexte, "+" signifie "n'importe lequel de ces bits est activé" et 111 est le bit d'exécution.

Notez que ce n'est pas identique à la -executable dans GNU find. En particulier, -executable vérifie que le fichier peut être exécuté par l'utilisateur actuel, tandis que -perm +111 teste seulement si des autorisations d'exécution sont définies.

Les anciennes versions de GNU find supportent également l'option -perm +111 mais à partir de 4.5.12 cette syntaxe n'est plus supportée. À la place, vous pouvez utiliser -perm /111 pour obtenir ce comportement.

0 votes

Erreur find: invalid mode ‘+111’ sur findutils 4.5.11 4.fc20.

1 votes

@sourcejedi Merci. En fait, je ne parlais que des versions non-GNU de find (BSD, en particulier), mais les anciennes versions de GNU find supportaient également cette syntaxe. Dans les versions plus récentes, vous devrez utiliser / au lieu de + . Voir la réponse mise à jour pour plus de détails.

0 votes

En effet, j'ai mal lu votre réponse. Désolé d'avoir rendu les choses plus compliquées :).

37voto

mklement0 Points 12597

Coup de chapeau à @ gniourf_gniourf pour avoir clarifié une idée fausse et fondamentale.

Cette réponse tente de fournir une vue d'ensemble des réponses existantes et de discuter de leurs subtilités et mérites relatifs ainsi que de fournir informations générales notamment en ce qui concerne portabilité .

La recherche de fichiers exécutables peut se référer à deux cas d'utilisation distincts :

  • centré sur l'utilisateur : trouver les fichiers qui sont exécutable par l'utilisateur actuel .
  • centré sur les fichiers : trouver les fichiers qui ont (un ou plusieurs) bits de permission de l'exécutable set .

Notez que dans soit scénario, il peut être judicieux de utiliser find -L ... au lieu de simplement find ... afin de trouver aussi liens symboliques vers exécutables .

Notez que le cas le plus simple, centré sur les fichiers, qui consiste à rechercher les exécutables dont le bit d'autorisation d'exécution est activé pour TOUS les trois principes de sécurité (utilisateur, groupe, autre), aura pour conséquence de généralement mais pas nécessairement donnent les mêmes résultats que le scénario centré sur l'utilisateur - et il est important de comprendre la différence.

Centré sur l'utilisateur ( -executable )

  • Le site réponse acceptée recommande chaudement -executable , IF GNU find est disponible.

    • GNU find est livré avec la plupart des Linux distros
      • En revanche, les plateformes basées sur BSD, dont macOS, sont livrées avec BSD find, qui est moins puissant.
    • Comme l'exige le scénario, -executable ne correspond qu'aux fichiers pour lesquels le utilisateur actuel peuvent s'exécuter (il y a des cas limites. [1] ).
  • Le site BSD find alternative offerte par la réponse acceptée ( -perm +111 ) réponses a différents , fichier -Question centrée (comme l'indique la réponse elle-même).

    • En utilisant seulement -perm pour répondre à la utilisateur -La question centrée est impossible car ce qu'il faut, c'est relate le site du fichier l'identité de l'utilisateur et du groupe au de l'utilisateur actuel alors que -perm ne peut que tester le du fichier permissions.
      En utilisant uniquement POSIX find caractéristiques Il est impossible de répondre à cette question sans faire appel à des services publics externes.
    • Ainsi, le meilleur -perm peut faire (par lui-même) est un approximation de -executable . Peut-être qu'un plus près que -perm +111 est -perm -111 afin de trouver les fichiers dont le bit exécutable est activé pour TOUS les principes de sécurité (utilisateur, groupe, autre) - cela me semble être le scénario typique du monde réel. En prime, il est également conforme à POSIX (utilisez la commande find -L pour inclure les liens symboliques, voir plus loin pour une explication) :

      find . -type f -perm -111  # or: find . -type f -perm -a=x
  • La réponse de gniourf_gniourf fournit un vrai, l'équivalent portable de -executable en utilisant -exec test -x {} \; bien que au détriment de la performance .

    • Combinaison de -exec test -x {} \; avec -perm +111 (c'est-à-dire les fichiers avec au moins un bit exécutable activé) peut améliorer les performances dans ce cas. exec ne doit pas être invoquée pour chaque (ce qui suit utilise l'équivalent conforme à POSIX de BSD find -perm +111 / GNU find -perm /111 (voir plus loin pour une explication) :

      find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print

Centré sur les fichiers ( -perm )

  • A réponse fichier -questions centrées il est Il suffit d'utiliser le système POSIX -perm primaire (connu sous le nom de test dans la terminologie de GNU find).
    • -perm vous permet de tester tout les autorisations de fichiers, et pas seulement l'exécutabilité.
    • Les permissions sont spécifiées soit comme octal ou modes symboliques . Les modes octaux sont des nombres octaux (par exemple , 111 ), tandis que les modes symboliques sont des chaînes de caractères (par exemple, a=x ).
    • Modes symboliques identifier les principes de sécurité comme u (utilisateur), g (groupe) et o (autre), ou a pour faire référence aux trois. Les permissions sont exprimées sous la forme x pour exécutable, par exemple, et affectées aux mandants à l'aide d'opérateurs = , + et - ; pour un Pour une discussion complète, y compris sur les modes octaux, voir la spécification POSIX pour le chmod utilitaire .
    • Dans le cadre de find :
      • Préfixer un mode avec - (par exemple, -ug=x ) signifie : correspondre aux fichiers qui ont tous les permissions spécifié (mais les fichiers correspondants peuvent avoir des autorisations supplémentaires).
      • Avoir PAS de préfixe (par exemple 755 ) signifie : correspondre aux fichiers qui ont cette complet, exact ensemble de permissions.
      • Caveat : Les deux GNU find et BSD find mettre en œuvre un supplémentaire, non standard préfixe avec sont-ANY-of-the-specified-permission-bits-set logique mais faites-le avec syntaxe incompatible :
        • Trouver BSD : +
        • GNU find : / [2]
      • Par conséquent, éviter ces extensions, si votre code doit être portable .
  • Les exemples ci-dessous présentent des réponses portables à diverses questions relatives aux fichiers.

Exemples de commandes centrées sur les fichiers

Note :

  • Les éléments suivants les exemples sont conformes à POSIX ce qui signifie qu'ils doivent fonctionner dans n'importe quelle implémentation compatible POSIX, y compris GNU find et BSD find ; en particulier, cela requiert :
    • NE PAS utiliser de préfixes de mode non standard + ou / .
    • En utilisant les formes POSIX de l'option Primaires d'opérateurs logiques :
      • ! pour NOT (GNU find et BSD find autorisent également -not ) ; notez que \! est utilisé dans les exemples afin de protéger ! des expansions de l'histoire des coquillages
      • -a pour ET (GNU find et BSD find permettent également -and )
      • -o pour OR (GNU find et BSD find autorisent également -or )
  • Les exemples utilisent symbolique car ils sont plus faciles à lire et à retenir.
    • Avec préfixe de mode - le = et + peuvent être utilisés de manière interchangeable (par exemple, -u=x est équivalent à -u+x - sauf si vous appliquez -x plus tard, mais ce n'est pas la peine de le faire).
    • Utilisez , pour joindre des modes partiels ; la logique ET est implicite ; par exemple, -u=x,g=x signifie que l'utilisateur et le bit exécutable du groupe doit être activé.
    • Les modes ne peuvent pas eux-mêmes n'exprime pas la correspondance négative dans le sens de "ne correspondre que si ce bit n'est PAS activé" ; vous devez utiliser un fichier séparé -perm avec l'expression NOT primaire, ! .
  • Notez que l'équipe de find primaires (par exemple -print ou -perm ; également connu sous le nom de actions et tests dans GNU find) sont implicitement joint à -a (ET logique), et que -o et éventuellement des parenthèses (échappées comme \( et \) pour l'obus) sont nécessaires pour mettre en œuvre la logique OR.
  • find -L ... au lieu de simplement find ... est utilisé afin de correspondre également à liens symboliques vers exécutables

    • -L indique à find d'évaluer le cibles de liens symboliques au lieu des liens symboliques eux-mêmes. -L , -type f ignore complètement les liens symboliques.

    Match files that have ALL executable bits set - for ALL 3 security

    principals (u (user), g (group), o (others)) and are therefore executable

    by anyone.

    This is the typical case, and applies to executables in system locations

    (e.g., /bin) and user-installed executables in shared locations

    (e.g., /usr/local/bin), for instance.

    find -L . -type f -perm -a=x # -a=x is the same as -ugo=x

    The POSIX-compliant equivalent of -perm +111 from the accepted answer:

    Match files that have ANY executable bit set.

    Note the need to group the permission tests using parentheses.

    find -L . -type f ( -perm -u=x -o -perm -g=x -o -perm -o=x )

    A somewhat contrived example to demonstrate the use of a multi-principial

    mode (comma-separated clauses) and negation:

    Match files that have both the user and group executable bit set, while

    also not having the other executable bit set.

    find -L . -type f -perm -u=x,g=x ! -perm -o=x


[1] Description de -executable de man find à partir de GNU find 4.4.2 :

Fait correspondre les fichiers qui sont exécutables et les répertoires qui sont consultables (au sens de la résolution des noms de fichiers). Cela prend en compte les listes d'accès et autres artefacts de permissions que le test -perm ignore. Ce test utilise l'appel système access(2) et peut donc être trompé par les serveurs peut donc être trompé par les serveurs NFS qui font du mappage d'UID (ou Root-squashing), puisque de nombreux systèmes implémentent access(2) dans le noyau du client et ne peuvent donc pas utiliser les informations de mappage d'UID. client et ne peuvent donc pas utiliser les informations de mappage d'UID détenues par le serveur. Comme ce test est basé uniquement sur le résultat de l'appel système access(2), il n'y a pas de système access(2), il n'y a aucune garantie qu'un fichier pour lequel ce test réussit puisse réellement être exécuté.

[2] Versions de GNU find plus ancien que 4.5.12 a également autorisé le préfixe + mais cette fonction a d'abord été dépréciée, puis supprimée, parce que la combinaison de l'option + avec symbolique donne probablement des résultats inattendus parce qu'elle est interprétée comme une exact masque de permissions. Si vous (a) exécutez sur une version avant 4.5.12 et (b) se limiter à octal uniquement, vous pourrait s'en tirer en utilisant + avec les deux GNU find et BSD find, mais ce n'est pas une bonne idée.

3 votes

La réponse la plus complète jamais donnée à SO ;)

0 votes

@andynormancx :) Eh bien, en termes de nombre de points, je peux offrir ce concurrent .

12voto

gniourf_gniourf Points 9393

Afin d'avoir une autre possibilité 1 pour trouver les fichiers qui sont exécutables par l'utilisateur actuel :

find . -type f -exec test -x {} \; -print

(la commande de test ici est celle qui se trouve dans PATH, très probablement /usr/bin/test et non le module intégré).


1 Ne l'utilisez que si le -executable drapeau de find n'est pas disponible ! Ceci est subtilement différent de l'option -perm +111 solution.

0 votes

Si vous êtes en colère, laissez une note pour expliquer pourquoi (vous pensez) que ma réponse n'est pas utile ou est fausse.

2 votes

Cela fonctionne, mais c'est assez lent. De plus, selon l'interpréteur de commandes, il peut être nécessaire d'envelopper ou d'échapper le caractère de remplacement du nom de fichier, par exemple '{}' ou \{\} .

1 votes

@mklement0 cela ne trouvera pas les commandes qui sont exécutables par moi comme -executable ou comme mon commandement le fait.

10voto

codaddict Points 154968

Vous pouvez utiliser le -executable drapeau de test :

-executable
              Matches files which are executable  and  directories  which  are
              searchable  (in  a file name resolution sense).

4 votes

-executable est censé être une option inconnue.

4 votes

Serait-ce une extension de GNU Find ? Puisque l'étiquette est Unix, et non Linux, une extension GNU doit au moins être documentée comme telle.

3 votes

Cette option n'est pas prise en charge par la commande BSD find que l'on trouve au moins sous OS X. Il s'agit d'une extension GNU, mais elle peut être supportée par d'autres versions de find.

3voto

louigi600 Points 440
find . -executable -type f

ne garantit pas vraiment que le fichier est exécutable ; il trouvera les fichiers dont le bit d'exécution est activé. Si vous faites

chmod a+x image.jpg

la recherche ci-dessus pensera que image.jpg est un exécutable même s'il s'agit en fait d'une image jpeg avec le bit d'exécution activé.

Je contourne généralement le problème avec cela :

find . -type f -executable -exec file {} \; | grep -wE "executable|shared object|ELF|script|a\.out|ASCII text"

Si vous voulez que le find imprime réellement des informations sur le dôme des fichiers exécutables, vous pouvez faire quelque chose comme ceci :

find . -type f -executable -printf "%i.%D %s %m %U %G %C@ %p" 2>/dev/null |while read LINE
do
  NAME=$(awk '{print $NF}' <<< $LINE)
  file -b $NAME |grep -qEw "executable|shared object|ELF|script|a\.out|ASCII text" && echo $LINE
done

Dans l'exemple ci-dessus, le chemin d'accès complet du fichier se trouve dans le dernier champ et doit refléter l'endroit où vous le recherchez avec awk "NOM=$(awk '{print $NF}' << $LINE)". si le nom du fichier se trouvait ailleurs dans la chaîne de sortie find, vous devez remplacer "NF" par la position numérique correcte. Si votre séparateur n'est pas un espace, vous devez également indiquer à awk quel est votre séparateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X