Como posso contar todos os scripts python e shell em todo o meu sistema?
Responder1
Na ausência de um objetivo mais específico, isso será aproximado, não importa como você o faça, devido a ambigüidades sobre o que constitui um script shell e o que constitui um script Python. Isso não torna o problema muito mal definido,contanto que uma aproximação seja o que você deseja. E você pode obter uma boa aproximação.
Diante disso, sugiro este comando para listar scripts shell e Python:
find . -type f -executable -exec file {} + | grep -Ei '(python|shell) script,'
Se a saída parecer razoável para suas necessidades, você poderá executá-la novamente, modificada para contar o número de resultados:
find . -type f -executable -exec file {} + | grep -Ei '(python|shell) script,' | wc -l
Você pode receber alguns erros de "Permissão negada". Tudo bem. Não recomendo tentar suprimir essas mensagens de erro, porque você deve lê-las ou pelo menos examiná-las para ver se parece que não conseguiu acessar nenhum arquivo ou local de seu interesse. Você pode executar o find
comando como root sudo
se realmente quiser.
-type f
faz com que encontre apenas arquivos regulares. Normalmente é melhor incluir-xtype f
links simbólicos que resolvem arquivos regulares, mas neste caso isso resultaria em contagem excessiva.-executable
faz com que ele encontre apenas arquivos executáveis pelo usuário que executa ofind
. Examinar arquivos não executáveis para ver se eles parecem ser scripts shell ou Python faria com que o comando demorasse consideravelmente mais. Você também pode obter mais falsos positivos dessa forma, pois os arquivos que não são executáveis podem ser "bibliotecas" em vez de scripts, ou seja, eles podem consistir em comandos shell e ser destinados ao fornecimento com.
ousource
em scripts shell, ou podem ser Módulos Python que seriam importados comimport
oufrom
para programas Python. (Você pode pensar que isso não aconteceria, já que esses arquivos geralmente não possuem umShebang, masfind
procura mais do que apenas uma coisa.) No entanto, você pode omitir-executable
se quiser - ese você estiver disposto a esperarconforme seu comando tenta abrir e ler o início de cada arquivo normal em seu sistema.-exec ... +
executa um comando...
com os arquivos encontrados como argumentos de linha de comando. Ele executa o comando quantas vezes forem necessárias para processar todos os arquivos. Freqüentemente, isso acontece apenas uma vez; para todos os arquivos executáveis em todo o sistema, provavelmente será mais de uma vez, mas muito menos vezes do que se você executasse uma vez por arquivo (como-exec ... \;
faria). Mesmo no mesmo número de arquivos, executar um comando menos vezes tende a ser notavelmente mais rápido do que executá-lo mais vezes, porque há menor sobrecarga associada.- O
file
comando olha o início de um arquivo e adivinha, geralmente muito bem, que tipo de arquivo é. A saída é em formato de duas colunas, com o caminho ou nome do arquivo à esquerda e um resumo do quetipodo arquivo parece estar à direita. - O
grep
comando filtra sua entrada e gera apenas linhas que não diferenciam maiúsculas de minúsculas (-i
) correspondem aoexpressão regular estendida(-E
)(python|shell) script,
. Essas são as linhas que contêm o textopython script,
,shell script,
ou qualquer variante maiúscula do mesmo. Os arquivosfind
identificam como esses tipos de scripts mostrarão isso. wc -l
, que aparece no segundo dos dois comandos mostrados acima, conta linhas.
Como mostrado, esta técnica é totalmente inadequada paramuitostarefas que envolvem discernir que tipo de arquivos se possui.O motivo é que um arquivo pode ter texto como python script,
em seu nome, bem como caracteres de nova linha em seu nome, o que faria com que a saída file
não fosse uma por linha.Geralmente é importante, e muitas vezes até vital, explicar tais coisas, e isso pode ser feito.Neste caso, entretanto, você está apenas buscando uma estimativa (devido à natureza confusa do problema em si) e parece que você não está renomeando, modificando, excluindo ou mesmo criando nada com base diretamente no resultado, então eu não acho que valha a pena se preocupar com isso. Se você acabar repetindo isso e definindo o problema de forma mais estrita, pode valer a pena resolver isso.
Observe que há um caso importante em que você pode querer considerar arquivos não executáveis como scripts: se você tiver muitos scripts Python trazidos de um sistema como o Windows, onde eles não estão marcados como executáveis. Nesse caso, você pode procurar .py
arquivos, mas esteja ciente de que muitos deles provavelmente serão módulos Python em vez de scripts Python. Se a boa prática do Python de colocar um hashbang no topo do script foi seguida (isso é útil até mesmo no Windows, porque py.exe
e pyw.exe
reconhecê-los, embora infelizmente nem sempre seja feito), então uma técnica que procura apenas por hashbangs, mas ignora se um arquivo executável pode ser mais adequado às suas necessidades.
Há também um caso menor, mas significativo, em que você pode querer considerar arquivos não executáveis como scripts de qualquer tipo - ou, mais precisamente, em que você pode querer testar a executabilidade de maneira diferente. Se você tiver uma unidade montada noexec
, nenhum arquivo nela passará find
no -executable
teste. Observe que este é um problema diferente de executar find
como um usuário que não tem permissão para executar alguns arquivos - como o problema de executá-lo como um usuário que não tem permissão para procurar em alguns diretórios, isso pode ser resolvido por executá-lo como um usuário suficientemente privilegiado.
Este problema,como você colocou, é incomum--normalmente alguém desejaria encontrar scripts de um idioma específico ou de uma pequena família de idiomas intimamente relacionados. Mas, para o benefício de futuros leitores, observe que encontrar todos os scripts de shell (por exemplo) em um único diretório, talvez grande, também pode ser conseguido com uma ligeira modificação nos comandos acima. (O mesmo vale para a técnica apresentada emResposta do WinEunuuchs2Unix--é útil para isso também.)
Por exemplo, para localizar todos os scripts de shell no diretório atual:
find . -type f -executable -exec file {} + | grep -Fi 'shell script,'
Responder2
Visão geral rápida
Aqui está uma orientação sobre como fazer isso.
$ for f in * ; do file "$f" ; done
aptfielout: ASCII text, with very long lines
aptfilein: ASCII text, with very long lines
aptfileout: ASCII text
aptfileparse.sh: Bourne-Again shell script, ASCII text executable, with very long lines
aptfileparse.sh~: ASCII text, with very long lines
calc.py: Python script, UTF-8 Unicode text executable
catall.sh: Bourne-Again shell script, ASCII text executable
Remova todos os arquivos que não dizem "script de shell Bourne-Again" ou "script Python". Adicione à lista scripts shell POSIX:
$ file /bin/zgrep
/bin/zgrep: POSIX shell script, ASCII text executable
Uma resposta completa
/$ time find * -type f -print0 2>/dev/null | xargs -0 -P 8 file | \
sed 's/.*: //g' | sed 's/^ *//g' | \
grep -Eio 'shell script,|Python script,' | sort | uniq -c
19151 Python script,
127 python script,
18420 shell script,
real 16m14.939s
user 54m7.355s
sys 2m33.238s
Começando pela raiz ( /
) find
, todos os arquivos e canalizam para o xargs
comando como nomes terminados em zero byte.
O xargs
comando é executado em paralelo maximizando todas as 8 CPUs para um processamento mais rápido. Cada processo paralelo chama o file
comando que obtém uma descrição do arquivo conforme mostrado na seção anterior.
O grep
comando seleciona scripts shell e scripts python.
O sort
comando classifica os scripts shell e os scripts python juntos.
O uniq
comando conta as ocorrências de cada grupo.
curiosidades
Você pode realmente sobrecarregar seu sistema executando todas as 8 CPUs (no meu caso) de uma só vez:
A beleza do Linux transparece porque outros trabalhos como o gravador de tela .gif
e um vídeo rodando no terceiro monitor (TV de tela grande) continuam funcionando normalmente. O Linux não permite que o xargs file
comando atrapalhe o sistema.