"Tipos de arquivo" em um sistema Unix são coisas como arquivos comuns, diretórios, pipes nomeados, arquivos especiais de caracteres, links simbólicos etc. Estes são os tipos de arquivos que find
pode filtrar com sua opção -type
.
O utilitário find
não pode distinguir, por si só, entre um "script de shell", "arquivo de imagem JPEG" ou qualquer outro tipo de arquivo regular . Esses tipos de dados podem, no entanto, ser distinguidos pelo utilitário file
, que examina assinaturas específicas dentro dos próprios arquivos para determinar seu tipo.
Uma forma comum de rotular os diferentes tipos de arquivos de dados é pelo tipo MIME , e file
é capaz para determinar o tipo MIME de um arquivo.
Usando file
com find
para detectar o tipo MIME de arquivos regulares e use isso apenas para localizar scripts de shell:
find . -type f -exec sh -c '
case $( file -bi "$1" ) in
*/x-shellscript*) exit 0
esac
exit 1' sh {} ';' -print
ou, usando bash
,
find . -type f \
-exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';' \
-print
Adicione -name sunrise
antes do -exec
se você quiser apenas detectar scripts com esse nome.
O comando find
acima encontrará todos os arquivos regulares dentro ou abaixo do diretório atual, e para cada um desses arquivos, chame um shell script em linha curto. Este script executa file -bi
no arquivo encontrado e sai com um status de saída zero se a saída desse comando contiver a string /x-shellscript
. Se a saída não contiver essa cadeia, ela sairá com um status de saída diferente de zero, o que fará com que find
continue imediatamente com o próximo arquivo. Se o arquivo foi encontrado para ser um script de shell, o comando find
continuará a saída do nome do caminho do arquivo (o -print
no final, que também pode ser substituído por alguma outra ação).
O comando file -bi
gerará o tipo MIME do arquivo. Para um script de shell no Linux (e na maioria dos outros sistemas), isso seria algo como
text/x-shellscript; charset=us-ascii
enquanto em sistemas com uma variante um pouco mais antiga do utilitário file
, pode ser
application/x-shellscript
O bit comum é o /x-shellscript
de substring.
Note que no macOS, você teria que usar file -bI
em vez de file -bi
por causa de razões (a opção -i
faz algo bem diferente). A saída no macOS é semelhante à de um sistema Linux.
Você desejaria executar alguma ação personalizada em cada script de shell encontrado, você poderia fazer isso com outro -exec
no lugar dos comandos -print
nos find
acima, mas também seria possível fazer
find . -type f -exec sh -c '
for pathname do
case $( file -bi "$pathname" ) in
*/x-shellscript*) ;;
*) continue
esac
# some code here that acts on "$pathname"
done' sh {} +
ou, com bash
,
find . -type f -exec bash -c '
for pathname do
[[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue
# some code here that acts on "$pathname"
done' bash {} +
Relacionados: