¿Cómo puedo encontrar solo los archivos ejecutables en un determinado directorio en Linux?

159

¿Cómo puedo encontrar solo los archivos ejecutables en un determinado directorio en Linux?

HaiYuan Zhang
fuente
Aquí hay una especie de script BASH, no está mal es lo que puedo decir :) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar
¿Qué pasa con el uso del filecomando estándar ?
Avance el
55
Para cualquiera que quiera hacer esto en una Mac (probado en OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' Lo anterior enumerará todos los ejecutables (para todos / usuario y grupo) en el directorio actual. Nota : La -executableopción no funciona en una Mac, de ahí la solución anterior.
techfoobar
También relevante: Unix find: busca archivos ejecutables
Slothworks
1
@techfoobar: La pregunta es ambigua: ¿significa archivos que contienen código ejecutable o archivos que tienen permiso ejecutable? Pero incluso si asumimos que el permiso ejecutable es lo que se desea (como parece la mayoría de las respuestas), la pregunta no dice ejecutable mundial . Su solución encontrará archivos (y también fifos, sockets, enlaces simbólicos, etc.) que tienen permiso de ejecución mundial, pero no 750 ( -rwxr-x---), que todavía es ejecutable para algunos usuarios.
G-Man

Respuestas:

158

La búsqueda de archivos ejecutables se puede hacer con -perm(no recomendado) o -executable(recomendado, ya que tiene en cuenta ACL). Para usar la -executableopción:

find <dir> -executable

si desea encontrar solo archivos ejecutables y directorios no buscables, combine con -type f:

find <dir> -executable -type f
knittl
fuente
23
un shebang no significa que sean ejecutables. solo nos dice qué intérprete usar. y por definición Linux “archivos ejecutables” son archivos con el archivo ejecutable (x) bit con valor
knittl
2
¿Qué versión de find admite ese tipo para -type? El hombre encuentra las listas b, c, d, p, f, l, sy D en mi sistema.
innaM
2
Lo mismo aquí, mi hallazgo no tiene -type xtampoco.
davr
77
Si tiene una versión anterior de find (probablemente anterior a 4.3.8) que carece de uso ejecutable find. -perma / u = x, g = x, o = x.
Ludwig Weinzierl
8
find: invalid predicate -executable'en RHEL
SSH Este
34

Usa la -permopción de búsqueda . Esto encontrará archivos en el directorio actual que sean ejecutables por su propietario, por miembros del grupo o por otros:

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

Editar:

Acabo de encontrar otra opción que está presente al menos en GNU find 4.4.0:

find . -executable

Esto debería funcionar aún mejor porque también se consideran las ACL.

innaM
fuente
2
Esto solo funciona en una versión más nueva de find. El que viene por defecto con CentOS da el error find: invalid mode / u = x, g = x, o = x'`
davr
12
Entonces deberías probar la versión "-perm +" que ahora está en desuso en GNU find: find. -perm +111 "
innaM
Parece que -perm /111puede ser la versión más portátil.
Scott
12

Sé que la pregunta menciona específicamente a Linux, pero dado que es el primer resultado en Google, solo quería agregar la respuesta que estaba buscando (por ejemplo, si usted, como yo en este momento, es forzado por su empleador a usar un GNU no / Sistema Linux).

Probado en macOS 10.12.5

find . -perm +111 -type f
Friederbluemle
fuente
1
Funciona en RHEL 5 también.
José Tomás Tocino
Esta es la única variante que podría trabajar en OS X 10.14, gracias
Justin
3

Tengo otro enfoque, en caso de que lo que realmente quiera sea hacer algo con archivos ejecutables, y no necesariamente forzar a find a que se filtre a sí mismo:

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

Prefiero esto porque no depende de -executablecuál es la plataforma específica; y no depende de -permcuál es un poco arcano, un poco específico de la plataforma, y ​​como está escrito anteriormente requiere que el archivo sea ejecutable para todos (no solo para usted).

Esto -type fes importante porque en los directorios * nix tienen que ser ejecutables para ser transitables, y cuanto mayor sea la consulta en el findcomando, más eficiente será la memoria de su comando.

De todos modos, solo ofrecemos otro enfoque, ya que * nix es la tierra de mil millones de enfoques.

Mark McKenna
fuente
(0) ¿Cuál prefieres, arcano y correcto o intuitivo y defectuoso? Prefiero correcto (1)  respuesta de innaM , que ofrece find -perm, encuentra los archivos que tienen cualquier ejecutar conjunto de permisos bits. (2) Por el contrario, esta respuesta solo encuentra archivos para los que el usuario actual tiene permiso de ejecución. De acuerdo, eso podría ser lo que quiere el OP, pero no está claro. ... (Continúa)
Scott
(Cont.) ... (3) Para mayor claridad, es posible que desee cambiar `…`a $(…)- vea esto , esto y esto . (4) Pero no lo hagas for i in $(find …); do …; falla en los nombres de archivo que contienen espacios. En cambio, hazlo find … -exec …. (5) Y, cuando trabaje con variables de shell, cítelas siempre (entre comillas dobles) a menos que tenga una buena razón para no hacerlo y esté seguro de saber lo que está haciendo.
Scott
@scott OK, estoy corregido :) Leí el -permargumento que requería los tres, no uno de ellos. Además, gracias por el aporte en la protección de los argumentos de shell, eso es todo lo que no conocía.
Mark McKenna
@ MarkMcKenna tienes un error tipográfico allí: for i in buscar. -tipo f ; do [ -x $i ] && echo "$i is executable"; done; te falta la parte <dir>, que uso un punto (.)
Devy
2

Un archivo marcado como ejecutable no necesita ser un archivo u objeto ejecutable o cargable.

Esto es lo que uso:

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
fuente
2
¿Qué hace esto?
DerMike
@DerMike, es una de las formas de encontrar ejecutables en el directorio actual, incluidos los archivos .so, incluso si un archivo no está marcado como ejecutable, puede descubrirlo.
AjayKumarBasuthkar
Bueno, quiero decir, ¿cómo hace eso?
DerMike
Se lee desde el encabezado del archivo para descubrir, cada archivo binario o archivo de script tiene encabezado.
AjayKumarBasuthkar
Hasta donde yo sé, -name "*"no tiene ningún efecto find: normalmente encuentra todos los archivos que no se eliminan mediante pruebas.
G-Man
1

Como fanático del único trazador de líneas ...

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

Usando 'xargs' para tomar la salida del comando find (usando print0 para asegurar que los nombres de archivo con espacios se manejen correctamente). Ahora tenemos una lista de archivos que son ejecutables y los proporcionamos, uno por uno, como parámetro para el comando 'archivo'. Luego grep para el término ASCII para ignorar los binarios. Sustituya -executable en el comando find con el estilo que prefiera (consulte las respuestas anteriores) o lo que funciona en su sistema operativo 'NIX

Requerí lo anterior para encontrar archivos con eval en scripts propiedad de root, así que creé lo siguiente para ayudar a encontrar debilidades de escalada privada donde el usuario root ejecuta scripts con parámetros inseguros ...

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
fuente
Eso no funcionará si el script contiene caracteres no ASCII. fileinforma la codificación, por lo que un script de Python se puede informar como a /usr/bin/python script, UTF-8 Unicode text executable. find ... | xargs file -b | grep -v '^ELF'podría funcionar mejor para detectar los no binarios.
xenoid
0

Creé una función ~/.bashrcesta noche para encontrar archivos ejecutables que no están en la ruta del sistema y no en los directorios:

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

La ventaja es que buscará tres distribuciones de Linux y una instalación de Windows en menos de un segundo, donde el findcomando tarda 15 minutos.

Por ejemplo:

$ 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

O para un directorio completo y todos sus subs:

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

real    0m0.741s
user    0m0.705s
sys     0m0.032s
WinEunuuchs2Unix
fuente