Como encontrar todos os executáveis ​​binários recursivamente dentro de um diretório?

46

Se eu usar findcomando como este:

find /mydir/mysubdir -executable -type f

todos os arquivos executáveis ​​são listados (excluindo diretórios) e incluindo o arquivo de script executável (como script.sh, etc). O que eu quero fazer é listar apenas arquivos executáveis ​​binários.

uray
fonte
1
Altere o assunto para incluir a palavra 'binário', essencial para responder à sua pergunta.
Stefan Lasiewski

Respostas:

44

Você pode tentar o fileutilitário. De acordo com a página de manual:

Os testes mágicos são usados ​​para verificar arquivos com dados em formatos fixos específicos. O exemplo canônico disso é um arquivo a.out executável binário (programa compilado), cujo formato é definido e, possivelmente, no diretório de inclusão padrão.

Você pode ter que brincar com a expressão regular, mas algo como:

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

O arquivo tem muitas opções, portanto, você pode dar uma olhada na página de manual. Eu usei a primeira opção que achei que parecia gerar uma saída fácil para grep.

Steven D
fonte
15
Eu diria que use find -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print. Ele só vai te dar os arquivos (e, portanto, pode ser passado para o próximo comando que ele quer correr)
Gert
A solução serverfault.com/a/584595/211551 localiza arquivos que NÃO são marcados como executáveis, mas são executáveis.
user2067125
No OS X, você pode instalar GNU findcom brew install findutilsou sudo port install findutilse, em seguida, você pode executar uma invocação como este para um efeito similar:gfind . -type f -executable -exec file '{}' \; | grep -i execut
PIB2
7

Aqui está uma maneira de excluir scripts, ou seja, arquivos cujos dois primeiros caracteres são #!:

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

Para alguns tipos de arquivos, não está claro se você deseja que eles sejam classificados como scripts ou binários, por exemplo, arquivos de bytecode. Dependendo de como as coisas estão configuradas, elas podem ou não começar #!. Se isso lhe interessa, você terá que tornar o script interno do shell mais complexo. Por exemplo, veja como você pode incluir binários ELF e executáveis ​​Mono e programas de bytecode Objective Caml, mas não outros tipos de executáveis, como shell scripts ou scripts perl ou programas de bytecode da 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- parar de ser mau'
fonte
2

Caso você se encontre em um sistema com nível inferior find(ainda existem, como eu escrevo, muitos clusters científicos executando o RHEL5!) Sem os direitos de atualização: em vez de

find /mypath/ -executable -type f

nas excelentes respostas acima, você pode fazer, por exemplo,

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

que pesquisa em bits de permissão. Infelizmente, o descrito acima apenas encontra arquivos para os quais o usuário tem executável, mas isso geralmente funciona para mim.

TomRoche
fonte
Isso ainda encontraria scripts executáveis, não apenas binários.
Kusalananda