¿Cómo encontrar todos los ejecutables binarios de forma recursiva dentro de un directorio?

46

Si uso un findcomando como este:

find /mydir/mysubdir -executable -type f

Todos los archivos ejecutables se enumeran (excluyendo directorios), e incluyendo el archivo de script ejecutable (como script.sh, etc.). Lo que quiero hacer es enumerar solo archivos ejecutables binarios.

uray
fuente
1
Cambie el tema para incluir la palabra 'binario', que es clave para responder a su pregunta.
Stefan Lasiewski

Respuestas:

44

Puedes probar la fileutilidad. Según la página del manual:

Las pruebas mágicas se utilizan para verificar archivos con datos en formatos fijos particulares. El ejemplo canónico de esto es un archivo binario ejecutable (programa compilado) a.out, cuyo formato se define y posiblemente en el directorio de inclusión estándar.

Puede que tenga que jugar con la expresión regular pero algo así como:

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

El archivo tiene muchas opciones, por lo que es posible que desee echar un vistazo más de cerca a la página del manual. Utilicé la primera opción que encontré que parecía dar salida fácilmente a grep.

Steven D
fuente
15
Yo diría usar find -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print. Solo le dará archivos (y, por lo tanto, puede pasar al siguiente comando que quiera ejecutar)
Gert
La solución serverfault.com/a/584595/211551 encuentra archivos que NO están marcados como ejecutables pero sí ejecutables.
user2067125
En OS X, puede instalar GNU findcon brew install findutilso sudo port install findutilsy luego puede ejecutar una invocación como esta con un efecto similar:gfind . -type f -executable -exec file '{}' \; | grep -i execut
GDP2
7

Aquí hay una manera de excluir scripts, es decir, archivos cuyos dos primeros caracteres son #!:

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

Para algunos tipos de archivos, no está claro si desea clasificarlos como scripts o binarios, por ejemplo, archivos de código de bytes. Dependiendo de cómo estén configuradas las cosas, estas pueden comenzar o no #!. Si esto te importa, tendrás que hacer que el script de shell interno sea más complejo. Por ejemplo, así es como puede incluir binarios ELF y ejecutables Mono y programas de código de bytes de Objective Caml, pero no otros tipos de ejecutables como scripts de shell o scripts de perl o programas 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
Gilles 'SO- deja de ser malvado'
fuente
2

En caso de que te encuentres en un sistema con un nivel inferior find(todavía hay, mientras escribo, ¡muchos grupos de ciencia que ejecutan RHEL5!) Sin los derechos para actualizar: en lugar de

find /mypath/ -executable -type f

en las excelentes respuestas anteriores, puede hacer, por ejemplo,

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

que busca en bits de permiso. Desafortunadamente, lo anterior solo encuentra archivos para los que el usuario tiene ejecutables, pero eso generalmente funciona para mí.

TomRoche
fuente
Esto todavía encontraría scripts ejecutables, no solo binarios.
Kusalananda