Mon problème (dans un script avec #!/bin/sh
) est le suivant: j'essaie de faire la somme de contrôle de tous les fichiers d'un répertoire à des fins d'archivage. Le fichier de somme de contrôle (dans mon cas sha1) avec tous les noms de fichiers doit résider dans le même répertoire. Disons que nous avons un répertoire ~/test
avec des fichiers f1
et f2
:.
mkdir ~/test
cd ~/test
echo "hello" > f1
echo "world" > f2
Calculons maintenant les sommes de contrôle avec
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum
fait exactement ce que je veux, il répertorie tous les fichiers du répertoire actuel uniquement et calcule les sommes sha1 (maxdepth peut être modifié ultérieurement). La sortie sur STDOUT est:
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
Malheureusement, lorsque vous essayez de l'enregistrer dans un fichier avec
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum > sums.sha1
le fichier résultant affiche la somme de contrôle pour lui-même:
da39a3ee5e6b4b0d3255bfef95601890afd80709 sums.sha1
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
et échoue donc à une date ultérieure shasum --check
, en raison du problème évident de modification de fichier supplémentaire lors de l'enregistrement de la dernière somme.
J'ai regardé autour de moi et en utilisant -p
flag for xargs
, j'ai découvert qu'il créait en quelque sorte le fichier de sortie avant même d'exécuter la commande find, donc le fichier supplémentaire est trouvé et sera additionné ...
Je sais que pour contourner ce problème, je pourrais enregistrer la somme de contrôle dans un autre emplacement (répertoire temporaire via mktemp
) ou l'exclure dans find spécifiquement, mais j'aimerais comprendre pourquoi il se comporte comme il le fait - ce qui, à mes yeux, n'est pas très utile, par exemple, si la première commande vérifiait si le fichier de sortie est déjà sur le disque, elle n'obtiendrait jamais la bonne réponse ...
sh
invocations sont nécessaires. Notez que vous avez besoin d'un argument pour $0
avant {}
.
tee
a disparu? Je l'ai essayé et cela fonctionne bien, j'ai également supprimé STDOUT avec l'ajout de 1>/dev/null
. Y a-t-il eu un problème avec la réponse ou était-ce un bug?
xargs
, c'est le shell lui-même qui crée ce fichier, car avant d'exécuter une commande, le shell redirige d'abord toutes les entrées, sorties et canaux, de sorte qu'aufind
démarrage, le fichier de sortie existe déjà. Utilisez à la-exec
place:find -maxdepth 1 -type f -exec sh -c 'shasum "$@" > sums.sha1' {} +