web-dev-qa-db-fra.com

Comment savoir si un fichier a plus de 30 minutes depuis / bin / sh?

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.

38
magol

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.

67
Schwern

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!

28
slebetman

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

16
alvherre

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;
9
Schwern

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) ))
5
tommy.carstensen

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
4
Rob Wells

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

2
mighty_mike

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 .

2
Dale Hagglund
#!/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
2
dderton

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.
}
0
Ondra Žižka
if [[ "$(date --rfc-3339=ns -r /tmp/targetFile)" < "$(date --rfc-3339=ns --date '90 minutes ago')" ]] ; then echo "older"; fi
0
user8050735