web-dev-qa-db-fra.com

Intelligent chmod -x pour tous les fichiers exécutables qui ne peuvent pas être exécutés

Shot in the sky: avez-vous un script qui exécute chmod -x sur tous les fichiers exécutables du système qui ne peuvent en réalité pas être exécutés (c'est-à-dire qu'ils ont, par erreur, le drapeau x_)?

(le contexte:
Après la copie des fichiers de sauvegarde de NTFS vers ext4, les fichiers sont devenus exécutables (html, md, txt, etc.). Je voudrais rendre les fichiers non exécutables, mais uniquement ceux qui sont vraiment non exécutables. Je devrais probablement écrire le script qui parcourt tous les fichiers du système (comme, par exemple, for f in ``find /path``; do intelligent_chmod -x $f; done;, où intelligent_chmod doit examiner le fichier et déterminer s'il s'agit du fichier ELF ou s'il a la première ligne !#..., etc.)

4
Ayrat

Ceci utilise find pour rechercher les fichiers normaux contenant le bit exécutable. Il les teste ensuite avec la commande file pour voir s’ils sont réellement des exécutables ou non. Sinon, nous lançons chmod a-x sur eux:

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

Comme vous pouvez le constater, cette commande find a deux expressions -exec qui sont connectées à un opérateur logique-OU.

Comment ça fonctionne

  • -type f -executable

    Ceci indique à find de ne rechercher que les fichiers normaux contenant le bit exécutable.

  • \(

    Cela commence un groupe.

    Par défaut, les conditions find sont AND-ed ensemble et AND est plus étroit que OR. Dans ce cas, nous voulons lier uniquement les deux commandes -exec suivantes avec un OR. Pour ce faire, nous avons besoin d'un groupe.

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

    Le programme file examine chaque fichier et grep vérifie si la chaîne executable figure dans le résultat de la commande file.

    Dans ce qui précède, Test sert de nom de programme ($0) pour le script sh -c. (Pour une discussion sur $0 et sh -c, voir cette question .)

    Voici un exemple de sortie de la commande 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
    

    Comme vous pouvez le constater, file est suffisamment intelligent pour être identifié comme étant un exécutable, non seulement les fichiers ELF, mais également une grande variété de fichiers de script.

  • -o

    C'est logique-OU. Cela signifie que la commande qui suit ne sera exécutée que si file n'a pas identifié le fichier en tant qu'exécutable.

  • -exec chmod a-x {} \;

    Cela supprime le bit exécutable.

  • \)

    Ceci indique à find que nous avons atteint la fin des commandes groupées.

Limites

Comme décrit dans man magic, le programme file fonctionne en examinant les chaînes d'un fichier. De nombreux fichiers ont des chaînes très distinctes. Un exécutable ELF, par exemple, commence par les caractères hexadécimaux 7f 45 4c 46. Les graphiques jpeg et png ont des marqueurs distincts de manière similaire. file n'analyse pas complètement un fichier et, par conséquent, pour certains fichiers, la magie échoue. Comme le souligne Ayrat dans les commentaires, file interprète mal ce qui suit:

$ 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
10
John1024