Dica do chapéu para @ gniourf_gniourf por esclarecer um equívoco fundamental.
Esta resposta tenta fornecer uma visão geral das respostas existentes e discutir suas sutilezas e méritos relativos , bem como fornecer informações básicas , especialmente no que diz respeito à portabilidade .
Encontrar arquivos executáveis pode se referir a dois casos de uso distintos :
- centrado no usuário : encontre arquivos executáveis pelo usuário atual .
- centralizado no arquivo : encontre arquivos que tenham (um ou mais) bits de permissão executáveis definidos .
Observe que em qualquer cenário pode fazer sentido usar emfind -L ...
vez de apenas find ...
para encontrar links simbólicos para executáveis .
Observe que o caso mais simples centrado em arquivo - procurando por executáveis com o bit de permissões executáveis definido para TODAS as três entidades de segurança (usuário, grupo, outro) - normalmente , mas não necessariamente produzirá os mesmos resultados que o cenário centrado no usuário - e é importante entender a diferença.
Centrado no usuário ( -executable
)
A resposta aceita recomenda com louvor -executable
, SE GNU find
estiver disponível.
- GNU
find
vem com a maioria do Linux distros
- Em contraste, plataformas baseadas em BSD, incluindo macOS, vêm com BSD find, que é menos poderoso.
- Conforme o cenário exige,
-executable
corresponde apenas aos arquivos que o usuário atual pode executar (há casos extremos. [1] ).
A alternativa BSD find
oferecida pela resposta aceita ( -perm +111
) responde a uma pergunta diferente , centrada em arquivo (como a própria resposta afirma).
- Usar apenas
-perm
para responder à pergunta centrada no usuário é impossível , porque o que é necessário é relacionar o usuário do arquivo e a identidade do grupo ao usuário atual , ao passo que -perm
só pode testar as permissões do arquivo .
Usando apenas recursos POSIXfind
, a pergunta não pode ser respondida sem envolver utilitários externos.
Assim, o melhor que -perm
podemos fazer (por si só) é uma aproximação de -executable
. Talvez uma aproximação mais próxima do que -perm +111
é-perm -111
, para encontrar arquivos que têm o bit executável definido para TODOS os princípios de segurança (usuário, grupo, outro) - isso me parece o cenário típico do mundo real. Como um bônus, ele também é compatível com POSIX (use find -L
para incluir links simbólicos, veja mais abaixo para uma explicação):
find . -type f -perm -111 # or: find . -type f -perm -a=x
A resposta de gniourf_gniourf fornece um equivalente verdadeiro e portátil de-executable
usar-exec test -x {} \;
, embora às custas do desempenho .
Combinar -exec test -x {} \;
com -perm +111
(ou seja, arquivos com pelo menos um conjunto de bits executáveis) pode ajudar no desempenho, pois exec
não precisa ser invocado para todos os arquivos (o seguinte usa o equivalente compatível com POSIX de BSD find -perm +111
/ GNU find -perm /111
; veja mais abaixo para uma explicação) :
find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print
Centrado no arquivo (-perm
)
- Para responder a perguntas centradas em arquivos , é suficiente usar o
-perm
primário compatível com POSIX (conhecido como teste na terminologia de localização do GNU).
-perm
permite que você teste quaisquer permissões de arquivo, não apenas a executabilidade.
- As permissões são especificadas como modos octal ou simbólico . Os modos octais são números octais (por exemplo,
111
), enquanto os modos simbólicos são strings (por exemplo, a=x
).
- Os modos simbólicos identificam os principais de segurança como
u
(usuário), g
(grupo) e o
(outro) ou a
para se referir a todos os três. As permissões são expressas como x
executáveis, por exemplo, e atribuídas aos principais usando operadores =
, +
e -
; para uma discussão completa, incluindo os modos octais, consulte a especificação POSIX do chmod
utilitário .
- No contexto de
find
:
- Prefixar um modo com
-
(por exemplo, -ug=x
) significa: combinar arquivos que têm todas as permissões especificadas (mas os arquivos correspondentes podem ter permissões adicionais).
- Não ter NENHUM prefixo (por exemplo
755
) significa: corresponder aos arquivos que possuem este completo, exato de permissões.
- Advertência : GNU find e BSD find implementam um prefixo não padrão adicional com a lógica de conjunto de bits de permissão especificada , mas fazem isso com sintaxe incompatível :
- BSD encontrar:
+
- GNU find:
/
[2]
- Portanto, evite essas extensões, se seu código deve ser portátil .
- Os exemplos abaixo demonstram respostas portáteis a várias perguntas centradas em arquivos.
Exemplos de comando centrado em arquivo
Nota:
- Os exemplos a seguir são compatíveis com POSIX , o que significa que devem funcionar em qualquer implementação compatível com POSIX, incluindo GNU find e BSD find; especificamente, isso requer:
- NÃO usa prefixos de modo não padrão
+
ou /
.
- Usando as formas POSIX das primárias do operador lógico :
!
para NOT (GNU find e BSD find também permitem -not
); note que \!
é usado nos exemplos para proteger !
de expansões de histórico de shell
-a
para AND (GNU find e BSD find também permitem -and
)
-o
para OR (GNU find e BSD find também permitem -or
)
- Os exemplos usam modos simbólicos , porque são mais fáceis de ler e lembrar.
- Com o prefixo de modo
-
, os operadores =
e +
podem ser usados alternadamente (por exemplo, -u=x
é equivalente a -u+x
- a menos que você aplique -x
mais tarde, mas não há porque fazer isso).
- Use
,
para entrar em modos parciais; A lógica AND está implícita; por exemplo, -u=x,g=x
significa que o bit executável do usuário e do grupo deve ser definido.
- Os modos não podem por si próprios expressar correspondência negativa no sentido de "corresponder apenas se este bit NÃO estiver definido"; você deve usar uma
-perm
expressão separada com o NOT primário !
,.
- Observe que as primárias de find (como
-print
, ou -perm
; também conhecidas como ações e testes em GNU find) são implicitamente associadas a-a
(AND lógico), -o
e possivelmente parênteses (com escape de \(
e\)
para o shell) são necessários para implementar a lógica OR.
find -L ...
em vez de apenas find ...
é usado para também corresponder links simbólicos para executáveis
-L
instrui o find para avaliar os alvos dos links simbólicos em vez dos próprios links simbólicos; portanto, sem -L
, -type f
iria ignorar os links simbólicos completamente.
# Match files that have ALL executable bits set - for ALL 3 security
# principals (u (user), g (group), o (others)) and are therefore executable
# by *anyone*.
# This is the typical case, and applies to executables in _system_ locations
# (e.g., /bin) and user-installed executables in _shared_ locations
# (e.g., /usr/local/bin), for instance.
find -L . -type f -perm -a=x # -a=x is the same as -ugo=x
# The POSIX-compliant equivalent of `-perm +111` from the accepted answer:
# Match files that have ANY executable bit set.
# Note the need to group the permission tests using parentheses.
find -L . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \)
# A somewhat contrived example to demonstrate the use of a multi-principial
# mode (comma-separated clauses) and negation:
# Match files that have _both_ the user and group executable bit set, while
# also _not_ having the other executable bit set.
find -L . -type f -perm -u=x,g=x \! -perm -o=x
[1] Descrição de -executable
partir man find
de GNU find 4.4.2:
Corresponde arquivos que são executáveis e diretórios que são pesquisáveis (no sentido de resolução de nome de arquivo). Isso leva em conta as listas de controle de acesso e outros artefatos de permissões que o teste -perm ignora. Este teste faz uso da chamada de sistema access (2), e então pode ser enganado por servidores NFS que fazem mapeamento UID (ou root-squash), uma vez que muitos sistemas implementam access (2) no kernel do cliente e então não podem fazer uso de as informações de mapeamento UID mantidas no servidor. Como esse teste é baseado apenas no resultado da chamada do sistema access (2), não há garantia de que um arquivo para o qual esse teste foi bem-sucedido possa realmente ser executado.
[2] GNU encontrar versões anteriores a 4.5.12 também permitia prefixo +
, mas primeiro foi descontinuado e eventualmente removido, porque a combinação +
com modos simbólicos provavelmente produz resultados inesperados devido a ser interpretado como uma máscara de permissões exata . Se você (a) executar em uma versão anterior a 4.5.12 e (b) se restringir a octais modos somente, você poderia fugir com o uso +
com ambos GNU encontrar e achado BSD, mas não é uma boa idéia.