Comment puis-je trouver uniquement les fichiers exécutables sous un certain répertoire sous Linux?

159

Comment puis-je trouver uniquement les fichiers exécutables sous un certain répertoire sous Linux?

HaiYuan Zhang
la source
Voici une sorte de script BASH, il est sans mauvais est ce que je peux dire :) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar
Qu'en est-il de l'utilisation de la filecommande standard ?
Percée
5
Pour tous ceux qui souhaitent le faire sur un Mac (testé sous OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' La liste ci-dessus répertorie tous les exécutables (pour tous / utilisateur et groupe) dans le répertoire actuel. Remarque : l' -executableoption ne fonctionne pas sur Mac, d'où la solution de contournement ci-dessus.
techfoobar
Également pertinent: Unix find: recherche de fichiers exécutables
Slothworks
1
@techfoobar: La question est ambiguë: s'agit-il de fichiers contenant du code exécutable ou de fichiers dotés d'une autorisation d'exécution? Mais même si nous supposons que l'autorisation exécutable est ce que nous souhaitons (comme le semblent la majorité des réponses), la question ne dit pas " exécutable dans le monde" . Votre solution trouvera des fichiers (ainsi que fifos, sockets, liens symboliques, etc.) disposant de l'autorisation d'exécution mondiale, mais pas 750 ( -rwxr-x---), qui est toujours exécutable par certains utilisateurs.
G-Man

Réponses:

158

La recherche de fichiers exécutables peut être effectuée avec -perm(non recommandé) ou -executable(recommandé, car elle prend en compte ACL). Pour utiliser l' -executableoption:

find <dir> -executable

Si vous souhaitez rechercher uniquement des fichiers exécutables et non des répertoires interrogeables, combinez-les avec -type f:

find <dir> -executable -type f
tricot
la source
23
un shebang ne signifie pas qu'ils sont exécutables. il nous dit seulement quel interprète utiliser. et par définition de linux «fichiers exécutables» sont des fichiers avec l'ensemble de bits exécutable (x)
knittl
2
Quelle version de find prend en charge ce type pour -type? man trouve les listes b, c, d, p, f, l, s et d de mon système.
innaM
2
Pareil ici, ma trouvaille n'en a pas non -type xplus.
davr
7
Si vous avez une ancienne version de find (probablement antérieure à 4.3.8) qui manque de -executable use find. -perm / u = x, g = x, o = x.
Ludwig Weinzierl
8
find: invalid predicate -executable'sur RHEL
SSH Ce
34

Utilisez l' -permoption de recherche. Cela permettra de trouver dans le répertoire en cours des fichiers exécutables par leur propriétaire, par les membres du groupe ou par d’autres personnes:

find . -perm /u=x,g=x,o=x

Modifier:

Je viens de trouver une autre option présente au moins dans GNU find 4.4.0:

find . -executable

Cela devrait fonctionner encore mieux, car les listes de contrôle d'accès sont également prises en compte.

innaM
la source
2
Cela ne fonctionne que sur une version plus récente de find. Celui qui vient par défaut avec CentOS donne l'erreur find: invalid mode / u = x, g = x, o = x'`
davr
12
Ensuite, vous devriez essayer la version "-perm +" qui est maintenant obsolète dans GNU find: find. -perm +111 "
innaM
On dirait que -perm /111peut être la version la plus portable.
Scott
12

Je sais que la question mentionne spécifiquement Linux, mais comme c'est le premier résultat sur Google, je voulais simplement ajouter la réponse que je cherchais (par exemple, si vous êtes - comme moi en ce moment - contraint par votre employeur d'utiliser un logiciel autre que GNU. / Système Linux).

Testé sur macOS 10.12.5

find . -perm +111 -type f
friederbluemle
la source
1
Fonctionne également dans RHEL 5.
José Tomás Tocino,
C’est la seule variante que je pourrais obtenir sur OS X 10.14, merci
Justin
3

J'ai une autre approche, au cas où vous voudriez vraiment faire quelque chose avec des fichiers exécutables - et pas nécessairement forcer find à se filtrer lui-même:

for i in `find -type f`; do [ -x $i ] && echo "$i is executable"; done

Je préfère ceci car il ne dépend pas de -executablece qui est spécifique à la plate-forme; et il ne dépend pas de -permce qui est un peu obscur, un peu spécifique à la plate-forme, et comme écrit ci-dessus, le fichier doit être exécutable pour tout le monde (pas seulement pour vous).

Ceci -type fest important parce que, dans * nix, les répertoires doivent être exécutables pour pouvoir être parcourus, et plus la requête contient de requêtes find, plus la commande sera économe en mémoire.

Quoi qu'il en soit, nous proposons simplement une autre approche, car * nix est le pays d’un milliard d’approches.

Mark McKenna
la source
(0) Que préférez-vous, mystérieux et correct ou intuitif et imparfait? Je préfère correct. (1)  La réponse de innaM , sélectionnée find -perm, recherche les fichiers pour lesquels un bit d'autorisation d'exécution est défini. (2) En revanche, cette réponse ne trouve que les fichiers pour lesquels l'utilisateur actuel dispose d'une autorisation d'exécution. Certes, c'est peut-être ce que souhaite le PO, mais ce n'est pas clair. … (Suite)
Scott
(Suite)… (3) Par souci de clarté, vous voudrez peut-être passer `…`à $(…)- voyez ceci , ceci et cela . (4) Mais ne fais pas for i in $(find …); do …; il échoue sur les noms de fichiers contenant des espaces. Au lieu de cela, faites find … -exec …. (5) Et, lorsque vous travaillez avec des variables de shell, citez-les toujours (entre guillemets) sauf si vous avez une bonne raison de ne pas le faire et que vous êtes certain de savoir ce que vous faites.
Scott
@ Scott OK, je suis corrigé :) J'ai lu l' -permargument comme exigeant les trois, pas un. Merci également pour vos commentaires sur la protection des arguments de shell, c'est tout ce dont je n'étais pas au courant.
Mark McKenna
@MarkMcKenna vous avez une faute de frappe ici: for i in trouver. -type f ; do [ -x $i ] && echo "$i is executable"; done; vous manquez la partie <dir>, que j'utilise avec un point (.)
Devy
2

Un fichier marqué comme exécutable ne doit pas nécessairement être un fichier ou un objet exécutable ou chargeable.

Voici ce que j'utilise:

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
AjayKumarBasuthkar
la source
2
Qu'est-ce que cela fait?
DerMike
@DerMike, c’est l’un des moyens de rechercher un exécutable dans le répertoire en cours, y compris les fichiers .so, même si un fichier n’est pas marqué comme exécutable, il peut le détecter.
AjayKumarBasuthkar
Eh bien, je veux dire, comment fait-il cela?
DerMike
Il lit à partir de l'en-tête du fichier à découvrir, chaque fichier binaire ou script a un en-tête.
AjayKumarBasuthkar
Autant que je sache, cela -name "*"n'a aucun effet find- il trouve normalement tous les fichiers qui ne sont pas éliminés par les tests.
G-Man
1

En tant que fan du one liner ...

find /usr/bin -executable -type f -print0 | xargs file | grep ASCII

Utilisation de 'xargs' pour extraire le résultat de la commande find (en utilisant print0 pour s'assurer que les noms de fichiers avec des espaces sont gérés correctement). Nous avons maintenant une liste de fichiers exécutables et nous les fournissons, un par un, en tant que paramètre de la commande 'file'. Puis grep pour le terme ASCII ignorer les fichiers binaires. Veuillez remplacer -executable dans la commande find par le style que vous préférez (voir les réponses précédentes) ou par ce qui fonctionne sur votre système d'exploitation NIX.

J'avais besoin de ce qui précède pour trouver des fichiers avec eval dans des scripts appartenant à root. C'est pourquoi nous avons créé ce qui suit pour aider à trouver les faiblesses de l'escalade privée dans lesquelles l'utilisateur root exécute des scripts avec des paramètres non sécurisés ...

echo -n "+ Identifying script files owned by root that execute and have an eval in them..."
find /  -not \( -path /proc -prune \)  -type f -executable -user root -exec grep -l eval {} \; -exec file {} \; | grep ASCII| cut -d ':' -f1 > $outputDir"/root_owned_scripts_with_eval.out" 2>/dev/null &
Richard Braganza
la source
Cela ne fonctionnera pas si le script contient des caractères non-ASCII. filerapporte l'encodage, donc un script python peut être rapporté comme a /usr/bin/python script, UTF-8 Unicode text executable. find ... | xargs file -b | grep -v '^ELF'pourrait mieux fonctionner pour repérer les non-binaires.
Xenoid
0

J'ai créé une fonction ~/.bashrcce soir pour trouver les fichiers exécutables qui ne se trouvent pas dans le chemin du système ni dans les répertoires:

# Quickly locate executables not in the path
xlocate () {
    locate -0r "$1" | xargs -0 -I{} bash -c '[[ -x "$1" ]] && [[ ! -d "$1" ]] \
        &&  echo "executable: $1"'  _  {}
} # xlocate ()

L'avantage est qu'il recherchera trois distributions Linux et une installation Windows en moins d'une seconde, la findcommande prenant 15 minutes.

Par exemple:

$ time xlocate llocate
executable: /bin/ntfsfallocate
executable: /home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/bin/ntfsfallocate
executable: /mnt/clone/home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/usr/bin/fallocate
executable: /mnt/e/bin/llocate
executable: /mnt/old/bin/ntfsfallocate
executable: /mnt/old/usr/bin/fallocate
executable: /usr/bin/fallocate

real    0m0.504s
user    0m0.487s
sys     0m0.018s

Ou pour tout un répertoire et tous ses sous-marins:

$ time xlocate /mnt/e/usr/local/bin/ | wc -l
65

real    0m0.741s
user    0m0.705s
sys     0m0.032s
WinEunuuchs2Unix
la source