web-dev-qa-db-fra.com

Comment trouver récursivement tous les exécutables binaires dans un répertoire?

Si j'utilise la commande find comme ceci:

find /mydir/mysubdir -executable -type f

tous les fichiers exécutables sont répertoriés (à l'exception des répertoires), y compris les fichiers de script exécutables (comme script.sh, etc.). Ce que je veux faire, c'est répertorier uniquement les fichiers exécutables binaires.

48
uray

Vous pouvez essayer l'utilitaire file. Selon la page de manuel:

Les tests magiques sont utilisés pour vérifier les fichiers contenant des données dans des formats fixes particuliers. L'exemple canonique de ceci est un fichier exécutable binaire (programme compilé) a.out, dont le format est défini dans, et éventuellement dans le répertoire include standard.

Vous devrez peut-être jouer avec l'expression régulière, mais quelque chose comme:

$ find -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary'

le fichier a beaucoup d'options, vous pouvez donc regarder de plus près la page de manuel. J'ai utilisé la première option que j'ai trouvée qui semblait produire une sortie facile à grep.

45
Steven D

Voici un moyen d'exclure des scripts, c'est-à-dire des fichiers dont les deux premiers caractères sont #!:

find -type f -executable -exec sh -c 'test "$(head -c 2 "$1")" != "#!"' sh {} \; -print

Pour certains types de fichiers, il n'est pas clair si vous souhaitez les classer en tant que scripts ou binaires, par exemple des fichiers de bytecode. Selon la façon dont les choses sont configurées, celles-ci peuvent commencer ou non par #!. Si cela vous intéresse, vous devrez rendre le script Shell interne plus complexe. Par exemple, voici comment vous pouvez inclure des binaires ELF et des exécutables Mono et des programmes de bytecode Objective Caml mais pas d'autres types d'exécutables comme des scripts Shell ou des scripts Perl ou des programmes de bytecode JVM:

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

Juste au cas où vous vous retrouveriez sur un système avec un niveau inférieur find (il y a encore, au moment où j'écris, beaucoup de clusters scientifiques exécutant RHEL5!) Sans les droits de mise à jour: au lieu de

find /mypath/ -executable -type f

dans les excellentes réponses ci-dessus, vous pouvez, par exemple,

find /mypath/h -type f -perm -u+x

qui recherche sur les bits d'autorisation. Malheureusement, ce qui précède ne trouve que les fichiers pour lesquels l'utilisateur a un exécutable, mais cela fonctionne généralement pour moi.

2
TomRoche