Como posso encontrar apenas os arquivos executáveis ​​em um determinado diretório no Linux?


157

Como posso encontrar apenas os arquivos executáveis ​​em um determinado diretório no Linux?


Aqui é uma espécie de script BASH, não é-ruim é o que posso dizer :) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar

Que tal usar o filecomando padrão ?
Breakthrough

5
Para quem quiser fazer isso em um Mac (testado no OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' O acima irá listar todos os executáveis ​​(para todos / usuário e grupo) no diretório atual. Nota : A -executableopção não funciona em um Mac, portanto, a solução alternativa acima.
techfoobar


1
@ techtobar: A pergunta é ambígua: significa arquivos que contêm código executável ou arquivos com permissão de executável? Mas mesmo se assumirmos que a permissão executável é o que se deseja (como parece a maioria das respostas), a pergunta não diz que é executável no mundo . Sua solução encontrará arquivos (e também fifos, sockets, links simbólicos etc.) que possuem permissão de execução mundial, mas não 750 ( -rwxr-x---), que ainda é executável para alguns usuários.
G-Man

Respostas:


157

A verificação de arquivos executáveis ​​pode ser feita com -perm(não recomendado) ou -executable(recomendado, pois leva em consideração a ACL). Para usar a -executableopção:

find <dir> -executable

se você deseja encontrar apenas arquivos executáveis ​​e diretórios não pesquisáveis, combine com -type f:

find <dir> -executable -type f

23
um shebang não significa que eles sejam executáveis. ele nos diz apenas qual intérprete usar. e, por definição linux “arquivos executáveis” são arquivos com o executável (x) bit conjunto
knittl

2
Qual versão do find suporta esse tipo de tipo? o homem encontra as listas b, c, d, p, f, l, se D no meu sistema.
innaM 10/09/09

2
Mesmo aqui, minha descoberta também não tem -type x.
davr 10/09/09

7
Se você possui uma versão antiga do find (provavelmente antes do 4.3.8) que não possui o uso -executable find. -perm / u = x, g = x, o = x.
Ludwig Weinzierl

8
find: invalid predicate -executable'on RHEL
SSH Este

33

Use a -permopção de localização. Isso encontrará arquivos no diretório atual que são executáveis ​​pelo proprietário, pelos membros do grupo ou por outros:

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

Editar:

Acabei de encontrar outra opção que está presente pelo menos no GNU find 4.4.0:

find . -executable

Isso deve funcionar ainda melhor porque as ACLs também são consideradas.


2
Isso funciona apenas em uma versão mais recente do find. O que vem por padrão com o CentOS dá o erro find: invalid mode / U = x, G = x, o = x'`
davr

12
Então você deve tentar a versão "-perm +" que agora está obsoleta no GNU find: find. +111 "
innaM 10/09/09

Parece que -perm /111pode ser a versão mais portátil.
Scott

12

Eu sei que a pergunta menciona especificamente o Linux, mas como é o primeiro resultado no Google, eu só queria adicionar a resposta que estava procurando (por exemplo, se você é - como eu no momento - forçado pelo seu empregador a usar um GNU não / Sistema Linux).

Testado no macOS 10.12.5

find . -perm +111 -type f

1
Também funciona no RHEL 5.
José Tomás Tocino

Esta é a única variante que eu poderia começar a trabalhar no OS X 10.14, thx
Justin

3

Eu tenho outra abordagem, caso o que você realmente queira seja fazer algo com arquivos executáveis ​​- e não necessariamente forçar a busca a se filtrar:

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

Eu prefiro isso porque não depende de -executablequal plataforma é específica; e não depende do -permque é um pouco misterioso, um pouco específico da plataforma e, conforme escrito acima, exige que o arquivo seja executável para todos (não apenas para você).

Isso -type fé importante porque os diretórios * nix precisam ser executáveis ​​para serem percorridos, e quanto mais a consulta estiver no findcomando, mais memória será eficiente.

De qualquer forma, basta oferecer outra abordagem, já que * nix é a terra de um bilhão de abordagens.


(0) Qual você prefere, misterioso e correto ou intuitivo e falho? Eu prefiro correto. (1)  a resposta do innaM , apresentando find -perm, localiza arquivos com qualquer bit de permissão de execução definido. (2) Por outro lado, esta resposta encontra apenas arquivos para os quais o usuário atual possui permissão de execução. É verdade que pode ser o que o OP quer, mas não está claro. ... (continua)
Scott

(Continua)… (3) Para maior clareza, convém mudar `…`para $(…)- veja isso , isso e isso . (4) Mas não faça for i in $(find …); do …; falha nos nomes de arquivos que contêm espaço (s). Em vez disso, faça find … -exec …. (5) E, quando você trabalha com variáveis ​​de shell, sempre as aspas (entre aspas duplas), a menos que você tenha um bom motivo para não fazê-lo e tenha certeza de que sabe o que está fazendo.
Scott

@ Scott Ok, eu estou corrigido :) Eu li o -permargumento como exigindo todos os três, não um deles. Além disso, obrigado pela entrada em proteger argumentos de shell, isso é tudo que eu não sabia.
Mark McKenna

@MarkMcKenna você tem um erro de digitação: for i in encontre. tipo f ; do [ -x $i ] && echo "$i is executable"; done; você está faltando o <dir> parte, que eu uso um ponto (.)
Devy

2

Um arquivo marcado como executável não precisa ser um arquivo ou objeto executável ou carregável.

Aqui está o que eu 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

2
O que isso faz?
DerMike 14/01

@ DerMike, é uma das maneiras de encontrar executáveis ​​no diretório atual, incluindo arquivos .so, mesmo que um arquivo não esteja marcado como executável, ele pode descobrir.
precisa saber é o seguinte

Bem, quero dizer, como isso acontece?
DerMike 15/01

Ele lê do cabeçalho do arquivo para descobrir, todo arquivo binário ou arquivo de script possui cabeçalho.
precisa saber é o seguinte

Até onde eu sei, -name "*"não tem efeito find- ele normalmente encontra todos os arquivos que não são eliminados pelos testes.
G-Man

1

Como um fã de um forro ...

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

Usando 'xargs' para obter a saída do comando find (usando print0 para garantir que os nomes de arquivos com espaços sejam manipulados corretamente). Agora temos uma lista de arquivos executáveis ​​e os fornecemos, um por um, como parâmetro para o comando 'file'. Então grep para o termo ASCII para ignorar binários. Substitua -executable no comando find por qual estilo você prefere (consulte as respostas anteriores) ou o que funciona no seu 'NIX OS

Eu exigi o acima para encontrar arquivos com avaliação em scripts pertencentes ao root, então criei o seguinte para ajudar a encontrar pontos fracos da escalação privada onde o usuário root executa scripts com 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 &

Isso não funcionará se o script contiver caracteres não ASCII. filerelata a codificação, para que um script python possa ser relatado como a /usr/bin/python script, UTF-8 Unicode text executable. find ... | xargs file -b | grep -v '^ELF'poderia funcionar melhor para identificar os não binários.
Xenoid

0

Criei uma função ~/.bashrchoje à noite para encontrar arquivos executáveis ​​que não estão no caminho do sistema e nem nos diretórios:

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

A vantagem é que ele pesquisará três distros do Linux e uma instalação do Windows em menos de um segundo, onde o findcomando leva 15 minutos.

Por exemplo:

$ 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 para um diretório inteiro e todos os seus subs:

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

real    0m0.741s
user    0m0.705s
sys     0m0.032s
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.