web-dev-qa-db-fra.com

Unix find: recherche de fichiers exécutables

Quel type de paramètre/indicateur puis-je utiliser avec la commande Unix find afin de rechercher les exécutables?

96
well actually

Sur les versions de 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 sont définis" et 111 sont les bits d'exécution.

Notez que ce n'est pas identique au -executable prédicat in GNU find. En particulier, -executable teste que le fichier peut être exécuté par l'utilisateur actuel, tandis que -perm +111 _ teste uniquement si des autorisations d'exécution sont définies.

Les anciennes versions de GNU find prennent également en charge le -perm +111 syntaxe, mais à compter de 4.5.12 , cette syntaxe n'est plus prise en charge. Au lieu de cela, vous pouvez utiliser -perm /111 pour obtenir ce comportement.

149
Laurence Gonsalves

Pour avoir une autre possibilité1 pour trouver les fichiers exécutables par l'utilisateur actuel:

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

(la commande de test ici est celle trouvée dans PATH, très probablement /usr/bin/test, pas la commande intégrée).


1 Utilisez-le uniquement si l'indicateur -executable De find n'est pas disponible! ceci est légèrement différent de la solution -perm +111.

9
gniourf_gniourf

Vous pouvez utiliser le -executable indicateur de test:

-executable
              Matches files which are executable  and  directories  which  are
              searchable  (in  a file name resolution sense).
9
codaddict
find . -executable -type f

ne garantit pas vraiment que le fichier est exécutable, il trouvera les fichiers avec le bit d'exécution défini. Si tu fais

chmod a+x image.jpg

la recherche ci-dessus va penser que image.jpg est un exécutable même s’il s’agit vraiment d’une image jpeg avec le bit d’exécution défini.

Je travaille généralement autour du problème avec ceci:

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

Si vous souhaitez que la recherche imprime réellement les informations du dôme sur les fichiers exécutables, vous pouvez procéder de la manière suivante:

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 indiquer où vous le cherchez avec awk "NAME = $ (awk '{print $ NF}' <<< $ LINE)" si le nom du fichier était ailleurs dans la chaîne de sortie de recherche dont vous avez besoin pour 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.

2
louigi600

Cela a fonctionné pour moi et pensé à partager ...

find ./ -type f -name "*" -not -name "*.o" -exec sh -c '
    case "$(head -n 1 "$1")" in
      ?ELF*) exit 0;;
      MZ*) exit 0;;
      #!*/ocamlrun*)exit0;;
    esac
exit 1
' sh {} \; -print
2
AjayKumarBasuthkar

Eh bien, la réponse la plus simple serait: "vos fichiers exécutables sont dans les répertoires contenus dans votre variable PATH", mais cela ne trouverait pas vraiment vos exécutables et vous risquez de rater de nombreux exécutables.

Je ne connais pas grand chose à propos de mac mais je pense que "mdfind 'kMDItemContentType = public.unix-executable'" pourrait manquer des choses comme des scripts interprétés

S'il est correct pour vous de trouver des fichiers avec les bits exécutables définis (qu'ils soient réellement exécutables), alors c'est bien de le faire

find . -type f -perm +111 -print

où pris en charge, l'option "-executable" créera un filtre supplémentaire en examinant les artefacts de permissions acl et autres, mais ne diffère pas du point de vue technique de "-pemr +111".

Peut-être que dans le futur, find prendra en charge "-magic" et vous permettra de rechercher explicitement les fichiers avec un identifiant magique spécifique ... mais vous devrez alors spécifier pour affiner tous les formats exécutables magic id.

Je ne suis pas au courant d'une solution de facilité techniquement correcte sous Unix.

1
louigi600

C’est SO ridicule que ce n’est pas très facile ... alors encore moins presque impossible . Les mains en l'air, je m'en remets à Apple/Spotlight ...

mdfind 'kMDItemContentType=public.unix-executable'

Au moins ça marche!

1
Alex Gray

J'ai eu le même problème, et la réponse était dans le code source de dmen : l'utilitaire stest conçu à cet effet. Vous pouvez compiler les fichiers 'stest.c' et 'arg.h' et cela devrait fonctionner. Il y a une page de manuel pour l'utilisation, que je mets là pour plus de commodité:

STEST(1)         General Commands Manual         STEST(1)

NAME
       stest - filter a list of files by properties

SYNOPSIS
       stest  [-abcdefghlpqrsuwx]  [-n  file]  [-o  file]
       [file...]

DESCRIPTION
       stest takes a list of files  and  filters  by  the
       files'  properties,  analogous  to test(1).  Files
       which pass all tests are printed to stdout. If  no
       files are given, stest reads files from stdin.

OPTIONS
       -a     Test hidden files.

       -b     Test that files are block specials.

       -c     Test that files are character specials.

       -d     Test that files are directories.

       -e     Test that files exist.

       -f     Test that files are regular files.

       -g     Test  that  files  have  their set-group-ID
              flag set.

       -h     Test that files are symbolic links.

       -l     Test the contents of a directory  given  as
              an argument.

       -n file
              Test that files are newer than file.

       -o file
              Test that files are older than file.

       -p     Test that files are named pipes.

       -q     No  files are printed, only the exit status
              is returned.

       -r     Test that files are readable.

       -s     Test that files are not empty.

       -u     Test that files have their set-user-ID flag
              set.

       -v     Invert  the  sense  of  tests, only failing
              files pass.

       -w     Test that files are writable.

       -x     Test that files are executable.

EXIT STATUS
       0      At least one file passed all tests.

       1      No files passed all tests.

       2      An error occurred.

SEE ALSO
       dmenu(1), test(1)

                        dmenu-4.6                STEST(1)
0
Josuah Demangeon

Donc, si vous voulez réellement trouver des types de fichiers exécutables (par exemple, des scripts, des binaires ELF, etc., etc.) et pas simplement des fichiers avec une exécution permission, alors vous voudrez probablement faire quelque chose de plus semblable à celui-ci (où peut être remplacé par le répertoire de votre choix):

 gfind . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print

Ou pour ceux d'entre vous qui n'utilisent pas macports (utilisateurs linux) ou qui ont installé gnu find en tant que find vous voulez:

 find . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print

Cependant, si vous utilisez OS X, il est livré avec un petit utilitaire caché quelque part, appelé is_exec, qui regroupe ce petit test pour vous, afin que vous puissiez raccourcir la ligne de commande si vous le trouvez. Mais cette méthode est plus souple car vous pouvez facilement remplacer le test == par le test = ~ et l'utiliser pour rechercher des propriétés plus complexes, telles que des fichiers texte brut exécutables ou toute autre information renvoyée par votre commande de fichier.


Les règles exactes pour la citation ici sont assez opaques, donc je finis par y arriver par essais et erreurs, mais j'aimerais entendre la bonne explication.

0
Peter Gerdes