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.)
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.
-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.
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