¿Cómo verifico en bash si un archivo se creó hace más de x veces?

106

Quiero comprobar en linux bash si un archivo se creó hace más de x veces.

digamos que el archivo se llama text.txt y el tiempo es de 2 horas.

 if [ what? ]
 then
     echo "old enough"
 fi
flybywire
fuente

Respuestas:

138

Solo por tiempo de modificación

if test `find "text.txt" -mmin +120`
then
    echo old enough
fi

Puede usar -cminpara cambiar o -aminpara tiempo de acceso. Como otros señalaron, no creo que puedas rastrear el tiempo de creación.

kmkaplan
fuente
3
puede quitar 'prueba' y las comillas invertidas. Esto es análogo a 'if (test == true)' vs 'if (test)'
guns
2
Estás en lo correcto; Supongo que estaba pensando que finddevolvió un valor distinto de cero cuando no se encontraron coincidencias.
armas
4
Puede quitar las comillas invertidas y hacer si prueba $ (busque text.txt -mmin +120)
tommy.carstensen
1
@BroSlow se ve mejor: no hay "más de uno" posible. Por supuesto, text.txtse presume que no es un directorio.
kmkaplan
2
Prefiero esta sintaxis:[ "$(find path/to/file -mmin +120)" ] && echo "it is old"
Alfe
42

Siempre me gustó usar date -r /the/file +%spara encontrar su edad.

También puede hacer touch --date '2015-10-10 9:55' /tmp/filepara obtener una hora extremadamente precisa en una fecha / hora arbitraria.

nemik
fuente
Hoy buscaba lo mismo. ¡Mejor!
Umair A.
Gracias. Llegué a esta pregunta SO porque busqué en Google "cómo imprimir la edad del archivo bash". ¡Así que esto es exactamente lo que estaba buscando!
Noah Sussman
5
¡Gracias! con la única salvedad de que lo anterior es una marca de tiempo (no la edad), pero se puede usar para calcular la edad así let AGE=$(($(date +%s)-$(date -r /path/to/file +%s))) [con el supuesto de que se creó y nunca se modificó, o "edad relativa a la modificación"]
nhed
function file-age { FILE_CREATED_TIME=`date -r "$1" +%s`; TIME_NOW=`date +%s`; echo "$[ ${TIME_NOW} - ${FILE_CREATED_TIME} ]"; }
turiyag
1
@turiyag Nota obligatoria que $[ ]es, si no obsoleta , al menos antiguo y menos portátil , y se debería usar $(( ))en su lugar; y las comillas inversas son más frágiles que $( ); Además, es posible que los guiones en los nombres de las funciones no sean completamente portátiles. ¡Sin embargo, la esencia es buena!
michaelb958 - GoFundMonica
23

Usando el statpara averiguar la fecha de la última modificación del archivo, datepara averiguar la hora actual y un uso liberal de bashisms, uno puede hacer la prueba que desee en función de la última hora de modificación del archivo 1 .

if [ "$(( $(date +"%s") - $(stat -c "%Y" $somefile) ))" -gt "7200" ]; then
   echo "$somefile is older then 2 hours"
fi

Si bien el código es un poco menos legible que el findenfoque, creo que es un enfoque mejor que ejecutarlo findpara ver un archivo que ya "encontró". Además, la manipulación de fechas es divertida ;-)


  1. Como Phil señaló correctamente, el tiempo de creación no se registra, sino que se usa en %Zlugar de a %Ycontinuación para obtener el "tiempo de cambio", que puede ser el que desee.

[Actualizar]

Para usuarios de mac, use en stat -f "%m" $somefilelugar de la sintaxis específica de Linux anterior

Guss
fuente
¿En qué shell están integrados la fecha y la estadística? Mi bash (GNU, 3.2.48) no los tiene.
Ian Clelland
Ups, lo siento. statno está incorporado - muy mal de mi parte, lo arreglaré.
Guss
1
La solución correcta de @Guss es instalar coretutils con brew. :-)
Erik Johansson
1
@ErikJohansson Prefiero no requerir la instalación de software adicional cuando el uso del existente funciona bien; esto no es Windows, ya sabes ;-)
Guss
1
Para las personas que quieran usar esto pero modificarlo, sería bueno saber exactamente qué está haciendo: $ (($ (fecha + "% s") - segundos desde 1970-01-01 00:00:00 UTC (Epoch) $ (stat -c "% Y" $ somefile))) - Hora de la última modificación en segundos desde Epoch -gt "7200" - comprueba si la diferencia es mayor que x número de segundos.
devo
16

El tiempo de creación no se almacena.

Lo que se almacena son tres marcas de tiempo (generalmente, se pueden desactivar en ciertos sistemas de archivos o mediante ciertas opciones del sistema de archivos):

  • Hora del último acceso
  • Hora de la última modificación
  • Hora del último cambio

un "Cambio" en el archivo se cuenta como cambios de permiso, cambio de nombre, etc. Mientras que la modificación es solo contenido.

Philip Reynolds
fuente
12

Aunque ctime no es técnicamente el momento de la creación, con bastante frecuencia lo es.

Dado que ctime no se ve afectado por los cambios en el contenido del archivo, generalmente solo se actualiza cuando se crea el archivo. Y sí, puedo escucharlos a todos gritar, también se actualiza si cambian los permisos de acceso o la propiedad ... pero generalmente eso es algo que se hace una vez, generalmente al mismo tiempo que coloca el archivo allí.

Personalmente siempre uso mtime para todo, e imagino que eso es lo que quieres. Pero de todos modos ... aquí hay una repetición de la fiesta "poco atractiva" de Guss, en una función fácil de usar.

#! / bin / bash
function age () {
   nombre de archivo local = $ 1
   local cambiado = `stat -c% Y" $ nombre de archivo "`
   local ahora = `fecha +% s`
   local transcurrido

   dejar transcurrido = ahora-cambiado
   echo $ transcurrido
}

file = "/"
echo La antigüedad de $ file es $ (age "$ file") segundos.
Maryam Jeddian
fuente
Esto fue útil, pero no funcionó de inmediato para OSX porque stat se implementa de manera diferente en él. La única forma compatible entre sistemas que encontré fue usar perl. El script debería funcionar en Mac si reemplaza la línea correspondiente con esto: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/…
Bijou Trouvaille
1
El "tiempo de creación" es un concepto difícil de comprender. ¿Qué significa para un archivo copiado? ¿Qué pasa con un archivo movido? ¿Qué pasa si se movió a través del borde de un dispositivo (por lo que se creó de nuevo, en cierto sentido)? ¿Qué significa para un archivo empaquetado y luego descomprimido? Aquí son posibles varias respuestas y no existe consenso. Sin embargo, mencionar el ctime es bueno, pero no lo pondría semánticamente cerca del vago concepto de "tiempo de creación". Sobre todo porque un simple chmod, aplicado en el archivo, anulará esa idea. Pero puedo vivir contigo haciendo eso ;-)
Alfe
@Alfe: Te estás perdiendo el +%sde la segunda mitad
Grizly
Esa edad puede ser mucho más corta: age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } (¡Gracias a @Grizly por la corrección!)
Alfe
En realidad, es mejor usar el tiempo de acceso, que es un tiempo de creación en todos los sistemas de archivos montados con la noatimeopción (lo cual es bueno para el rendimiento, por lo que debe usarlo). Así que usa en %Xlugar de %Y.
Nux
7

Encontrar uno es bueno, pero creo que puede usarlo de otra manera, especialmente si necesita saber cuántos segundos es el archivo antiguo.

date -d "now - $( stat -c "%Y" $filename ) seconds" +%s

usando la fecha GNU

Véase
fuente
use gstat, "brew install coreutils"
Erik Johansson
3

Considere el resultado de la herramienta 'stat':

  File: `infolog.txt'
  Size: 694         Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 11635578    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/     fdr)   Gid: ( 1000/     fdr)
Access: 2009-01-01 22:04:15.000000000 -0800
Modify: 2009-01-01 22:05:05.000000000 -0800
Change: 2009-01-01 22:05:05.000000000 -0800

Puede ver aquí las tres fechas para acceder / modificar / cambiar. No hay fecha de creación. Solo puede estar realmente seguro cuando se modificó el contenido del archivo (el campo "modificar") o se cambió su inodo (el campo "cambiar").

Ejemplos de cuándo se actualizan ambos campos:

"Modificar" se actualizará si alguien concatena información adicional al final del archivo.

"Cambiar" se actualizará si alguien cambia los permisos a través de chmod.

fdr
fuente
concedido, stat puede decirle información relevante. Pero será bastante tedioso analizar para obtener lo que queremos.
PypeBros
0

yo suelo

file_age() {
    local filename=$1
    echo $(( $(date +%s) - $(date -r $filename +%s) ))
}

is_stale() {
    local filename=$1
    local max_minutes=20
    [ $(file_age $filename) -gt $(( $max_minutes*60 )) ]
}

if is_stale /my/file; then
    ...
fi
xpmatteo
fuente