Le intégré test
et les [
utilitaires ont les tests -nt
("plus récent que") et -ot
("plus ancien que") dans la plupart des shells, même lorsque le shell s'exécute en "mode POSIX" (également vrai pour les utilitaires externes des mêmes noms sur le systèmes auxquels j'ai accès). Ces tests permettent de comparer les horodatages de modification sur deux fichiers. Leur sémantique documentée varie légèrement d'une implémentation à l'autre (en ce qui concerne ce qui se passe si l'un ou l'autre fichier n'existe pas), mais ils ne sont pas inclus dans la spécification POSIX. pour l' test
utilitaire .
Ils n'ont pas été reportés dans l'
test
utilitaire lorsque la commande conditionnelle a été supprimée du shell [KornShell] car ils n'ont pas été inclus dans l'test
utilitaire intégré aux implémentations historiques de l'sh
utilitaire.
En supposant que je voudrais comparer l'horodatage de modification entre les fichiers dans un /bin/sh
script shell et prendre des mesures selon que l' un fichier est plus récent que l'autre, comme dans
if [ "$sigfile" -nt "$timestamp" ] ||
[ "$sigfile.tmp" -nt "$timestamp" ]
then
return
fi
... quel autre utilitaire pourrais - je utiliser, à part make
( ce qui rendrait le reste du script trop compliqué pour le moins)? Ou devrais-je simplement supposer que personne ne va jamais exécuter le script sur une "implémentation historique de sh
", ou se résigner à écrire pour un shell spécifique comme bash
?
la source
-nt
fonctionnalité detest
manière attendue depuis env. 1995. Vous devriez utiliser l'find
expression basd mêmebash
si vous aimez un comportement correct.Réponses:
POSIX:
L'utilisation d'un chemin absolu vers les fichiers empêche un faux positif dont le nom de fichier contient uniquement des retours à la ligne.
En cas d'utilisation d'un chemin relatif, changez la
find
commande en:la source
$f1
ne contient que des nouvelles lignes;)-exec echo x \;
ou similaire?-printf
serait facile s'il était standardfind
est indépendant de ce que les tests defind
retour individuels - sauf peut-être s'il y a une erreur dans l'exécution de ces tests.find
quitte 0 même si aucun fichier n'est trouvé.[ / -nt /nofile ]
varie selon l'implémentation (mais ne génère jamais d'erreur).Cela pourrait être un cas pour l' utilisation de l' un des plus anciens commande Unix,
ls
.Le résultat est vrai si a est plus récent que b.
la source
-
(manquant--
). Vous auriez besoin-L
que ce soit équivalent à-nt
. Cela ne fonctionne pas pour comparerx
et$'x\nx'
par exemple.Vous avez soulevé une question intéressante et fait une affirmation qui devrait d'abord être vérifiée.
J'ai vérifié le comportement de:
avec différentes coquilles. Voici les résultats:
bash Ne fonctionne pas - n'imprime rien.
bosh fonctionne
tiret ne fonctionne pas - n'imprime rien.
ksh88 Ne fonctionne pas - n'imprime rien.
ksh93 fonctionne
mksh Ne fonctionne pas - n'imprime rien.
imprime chic : posh: [: -nt: opérateur / opérande inattendu
yash fonctionne
zsh fonctionne dans les versions plus récentes , les versions plus anciennes n'impriment rien
Ainsi, quatre des neuf shells prennent en charge la fonction -nt et l'implémentent correctement. Dans ce cas, correctement signifie: est capable de comparer les horodatages sur les plates-formes récentes qui prennent en charge la granularité d'horodatage en moins d'une seconde . Notez que les fichiers que j'ai sélectionnés ne diffèrent généralement que de quelques microsecondes dans leurs horodatages.
Puisqu'il est plus facile de trouver une
find
implémentation fonctionnelle , je recommande de remplacerpar une
find
expression basée.fonctionne au moins tant qu'il
$file1
ne contient pas seulement des retours à la ligne.est un peu plus lent mais fonctionne correctement.
BTW: En ce qui concerne make, je ne peux pas parler pour toutes les implémentations de make, mais
SunPro Make
prend en charge la comparaison du temps avec la granularité nanoseconde depuis env. 20 ans,smake
et agmake
récemment ajouté cette fonctionnalité.la source
find
implémentations telles que busybox ou heirloom-toolchest auront la même limitation.-L
que lafind
version soit équivalente à-nt
. Il échouerait également sur les noms de fichiers commençant par-
ou!
,(
...find
ontfind -f "$file"
ça mais ce n'est pas portable.