chmod -x inteligente para todos os arquivos executáveis que realmente não podem ser executados

3

Disparado no céu: você tem um script que faz chmod -x em todos os arquivos executáveis no sistema que realmente não podem ser executados (por exemplo, eles têm x flag erroneamente)?

(contexto:
Depois de copiar os arquivos de backup do NTFS para o ext4, os arquivos se tornaram executáveis (html, md, txt, etc.). Eu gostaria de tornar os arquivos não-executáveis, mas apenas aqueles que são realmente não-executáveis. Eu provavelmente terei que escrever o script que itera sobre todos os arquivos no sistema (assim como for f in ''find /path''; do intelligent_chmod -x $f; done; , onde intelligent_chmod tem que examinar o arquivo e identificar se ele é ELF ou tem a primeira linha !#... , etc. )

    
por Ayrat 10.08.2016 / 09:33

1 resposta

9

Isso usa find para procurar por arquivos regulares que tenham o bit executável definido. Em seguida, testa-os com o comando file para ver se eles são realmente executáveis ou não. Se não, corremos chmod a-x neles:

find . -type f -executable \( -exec sh -c 'file -b "$1" | grep -q executable' Test {} \; -o -exec chmod a-x {} \; \)

Como você pode ver, esse comando find tem duas expressões -exec conectadas a um operador lógico-OR.

Como funciona

  • -type f -executable

    Isso diz ao find para procurar apenas pelos arquivos regulares que possuem o bit executável definido.

  • \(

    Isso começa um grupo.

    Por padrão, find condições são AND-ed juntas e AND é mais restrito que OR. Nesse caso, queremos vincular apenas os dois comandos -exec a seguir junto com um OR. Para fazer isso, precisamos de um grupo.

  • -exec sh -c 'file -b "$1" | grep -q executable' Test {} \;

    Isso tem o programa file examinar cada arquivo e grep verifica se a string executable estava na saída do comando file .

    Acima, Test serve como o nome do programa ( $0 ) para o script sh -c . (Para uma discussão sobre $0 e sh -c , consulte esta questão .

    Aqui está um exemplo de saída do comando file :

    $ file -b bash
    ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=0e188133c8cc5187e22eabd27cbcf46f32060fe3, stripped        
    $ file -b which
    POSIX shell script, ASCII text executable
    

    Como você pode ver, file é inteligente o suficiente para identificar como executáveis não apenas arquivos ELF, mas também uma grande variedade de arquivos de script.

  • -o

    Isso é lógico-OR. Isso significa que o comando a seguir só será executado se file não identificar o arquivo como um executável.

  • -exec chmod a-x {} \;

    Isso remove o bit executável.

  • \)

    Isso diz ao find que chegamos ao final dos comandos agrupados.

Limitações

Conforme descrito em man magic , o programa file funciona examinando as cadeias de caracteres em um arquivo. Muitos arquivos têm cadeias muito distintas. Um executável ELF, por exemplo, começa com os caracteres hexadecimais 7f 45 4c 46 . Os gráficos jpeg e png têm marcadores similarmente distintos. file não analisa ou analisa completamente um arquivo e, conseqüentemente, para alguns arquivos, no entanto, a mágica falha. Como Ayrat aponta nos comentários, file interpreta erroneamente o seguinte:

$ cat tmp.py
Now is the time for all good men
to come to the aid of the party.
from xxx import yyy
$ file tmp.py
tmp.py: Python script, ASCII text executable
    
por John1024 10.08.2016 / 09:46