Comment écrire un script pour déterminer si un fichier a plus de 30 minutes dans/bin/sh?
Malheureusement, la commande stat
n'existe pas dans le système. C'est un ancien système Unix, http://en.wikipedia.org/wiki/Interactive_Unix
Perl n'est malheureusement pas installé sur le système et le client ne veut pas l'installer, et rien d'autre non plus.
Voici une façon d'utiliser find
.
if test "`find file -mmin +30`"
La commande find
doit être citée au cas où le fichier en question contient des espaces ou des caractères spéciaux.
Ce qui suit vous donne l'âge du fichier en secondes:
echo $(( `date +%s` - `stat -L --format %Y $filename` ))
ce qui signifie que cela devrait donner une valeur vraie/fausse (1/0) pour les fichiers de plus de 30 minutes:
echo $(( (`date +%s` - `stat -L --format %Y $filename`) > (30*60) ))
30*60
- 60 secondes en une minute, ne pas précalculer, laissez le CPU faire le travail pour vous!
Si vous écrivez un script sh, le moyen le plus utile est d'utiliser test
avec l'astuce de statistique déjà mentionnée:
if [ `stat --format=%Y $file` -le $(( `date +%s` - 1800 )) ]; then
do stuff with your 30-minutes-old $file
fi
Notez que [
est un lien symbolique (ou équivalent) à test
; voir man test
, mais gardez à l'esprit que test
et [
sont également des commandes bash et peuvent donc avoir un comportement légèrement différent. (Notez également le [[
commande bash compound).
Ok, pas de stat et une trouvaille paralysée. Voici vos alternatives:
Compilez le GNU coreutils pour obtenir une trouvaille décente (et beaucoup d'autres commandes pratiques). Vous l'avez peut-être déjà en tant que gfind.
Vous pouvez peut-être utiliser date
pour obtenir l'heure de modification du fichier si -r
travaux?
(`date +%s` - `date -r $file +%s`) > (30*60)
Vous pouvez également utiliser le -nt
comparaison pour choisir le fichier le plus récent, le problème est de créer un fichier avec un temps de modification de 30 minutes dans le passé. touch
peut généralement le faire, mais tous les paris sont désactivés sur ce qui est disponible.
touch -d '30 minutes ago' 30_minutes_ago
if [ your_file -ot 30_minutes_ago ]; then
...do stuff...
fi
Et enfin, voyez si Perl est disponible plutôt que de vous demander qui sait quelles versions des utilitaires Shell.
use File::stat;
print "Yes" if (time - stat("yourfile")->mtime) > 60*30;
Pour ceux comme moi, qui n'aiment pas les tiques de retour, selon la réponse de @slebetman:
echo $(( $(date +%s) - $(stat -L --format %Y $filename) > (30*60) ))
Pour ce faire, vous pouvez comparer un fichier de référence que vous avez créé avec un horodatage il y a trente minutes.
Créez d'abord votre fichier de comparaison en entrant
touch -t YYYYMMDDhhmm.ss /tmp/thirty_minutes_ago
remplacer l'horodatage par la valeur il y a trente minutes. Vous pouvez automatiser cette étape avec un liner trivial en Perl.
Ensuite, utilisez l'opérateur le plus récent de find pour faire correspondre les fichiers plus anciens en annulant l'opérateur de recherche
find . \! -newer /tmp/thirty_minutes_ago -print
Vous pouvez utiliser la commande find.
Par exemple, pour rechercher des fichiers de plus de 30 min dans le répertoire actuel:
find . -type f -mmin +30
Vous pouvez vous renseigner sur la commande find ICI
Qu'entendez-vous par plus de 30 minutes : modifié il y a plus de 30 minutes , ou créé il y a plus de 30 minutes ? J'espère que c'est la première, car les réponses jusqu'à présent sont correctes pour cette interprétation. Dans ce dernier cas, vous avez des problèmes car les systèmes de fichiers Unix ne suivent pas l'heure de création d'un fichier. (L'attribut de fichier ctime
enregistre la dernière modification du contenu de l'inode , c'est-à-dire quelque chose comme chmod
ou chown
s'est produit).
Si vous avez vraiment besoin de savoir si le fichier a été créé il y a plus de 30 minutes, vous devrez soit analyser la partie pertinente du système de fichiers à plusieurs reprises avec quelque chose comme find
ou utiliser quelque chose dépendant de la plate-forme comme linux - inotify .
#!/usr/bin/ksh
## this script creates a new timer file every minute and renames all the previously created timer files and then executes whatever script you need which can now use the timer files to compare against with a find. The script is designed to always be running on the server. The first time the script is executed it will remove the timer files and it will take an hour to rebuild them (assuming you want 60 minutes of timer files)
set -x
# if the server is rebooted for any reason or this scripts stops we must rebuild the timer files from scratch
find /yourpath/timer -type f -exec rm {} \;
while [ 1 ]
do
COUNTER=60
COUNTER2=60
cd /yourpath/timer
while [ COUNTER -gt 1 ]
do
COUNTER2=`expr $COUNTER - 1`
echo COUNTER=$COUNTER
echo COUNTER2=$COUNTER2
if [ -f timer-minutes-$COUNTER2 ]
then
mv timer-minutes-$COUNTER2 timer-minutes-$COUNTER
COUNTER=`expr $COUNTER - 1`
else
touch timer-minutes-$COUNTER2
fi
done
touch timer-minutes-1
sleep 60
#this will check to see if the files have been fully updated after a server restart
COUNT=`find . ! -newer timer-minutes-30 -type f | wc -l | awk '{print $1}'`
if [ $COUNT -eq 1 ]
then
# execute whatever scripts at this point
fi
done
Voici ma variation sur find
:
if [ `find cache/nodes.csv -mmin +10 | egrep '.*'` ]
Rechercher renvoie toujours le code d'état 0
sauf en cas d'échec; cependant, egrep
renvoie 1
aucune correspondance n'est trouvée ". Cette combinaison passe donc si ce fichier a plus de 10 minutes.
Essayez-le:
touch /tmp/foo; sleep 61;
find /tmp/foo -mmin +1 | egrep '.*'; echo $?
find /tmp/foo -mmin +10 | egrep '.*'; echo $?
Doit afficher 0 puis 1 après le chemin du fichier.
Ma fonction en utilisant ceci:
## Usage: if isFileOlderThanMinutes "$NODES_FILE_RAW" $NODES_INFO_EXPIRY; then ...
function isFileOlderThanMinutes {
if [ "" == "$1" ] ; then serr "isFileOlderThanMinutes() usage: isFileOlderThanMinutes <file> <minutes>"; exit; fi
if [ "" == "$2" ] ; then serr "isFileOlderThanMinutes() usage: isFileOlderThanMinutes <file> <minutes>"; exit; fi
## Does not exist -> "older"
if [ ! -f "$1" ] ; then return 0; fi
## The file older than $2 is found...
find "$1" -mmin +$2 | egrep '.*' > /dev/null 2>&1;
if [ $? == 0 ] ; then return 0; fi ## So it is older.
return 1; ## Else it not older.
}
if [[ "$(date --rfc-3339=ns -r /tmp/targetFile)" < "$(date --rfc-3339=ns --date '90 minutes ago')" ]] ; then echo "older"; fi