2010-03-19 12 views
6

Tengo problemas al usar os.utime para establecer correctamente el tiempo de modificación en el mac (Mac OS X 10.6.2, ejecutando Python 2.6.1 desde /usr/bin/python). No es coherente con la utilidad touch, y no es coherente con las propiedades que se muestran en la ventana "obtener información" del Finder.Inconsistencia en el tiempo modificado/creado/accedido en mac

Considere la siguiente secuencia de comandos. Los tiempos 'creado' y 'modificado' en el texto plano se refieren a los atributos que se muestran en la ventana "obtener información" en el buscador. Como recordatorio, os.utime toma argumentos (filename, (atime, mtime)).

>>> import os 
>>> open('tempfile','w').close() 

'created' y 'modified' son ambas la hora actual.

>>> os.utime('tempfile', (1000000000, 1500000000)) 

'creado' es la hora actual, 'modificado' se 13 de julio de 2017.

>>> os.utime('tempfile', (1000000000, 1000000000)) 

'creados' y 'modificada' son ambos 8 de septiembre de 2001.

>>> os.path.getmtime('tempfile') 
1000000000.0 
>>> os.path.getctime('tempfile') 
1269021939.0 
>>> os.path.getatime('tempfile') 
1269021951.0 

... pero os.path.get?time y os.stat no lo reflejan.

>>> os.utime('tempfile', (1500000000, 1000000000)) 

'creados' y 'modificada' son todavía tanto 8 de septiembre de 2001.

>>> os.utime('tempfile', (1500000000, 1500000000)) 

'creado' es 8 de septiembre de 2001, 'modificado' es 13 de julio de 2017.

No estoy seguro de si se trata de un problema de Python o de una estadística de Mac. Cuando salgo de la terminal de Python y correr

touch -a -t 200011221234 tempfile 

ni la modificación ni la creación tiempos cambian, como se esperaba. Luego ejecuto

touch -m -t 200011221234 tempfile 

y se modifican los tiempos tanto 'creados' como 'modificados'.

¿Alguien tiene alguna idea de lo que está pasando? ¿Cómo cambio los tiempos de modificación y creación consistentemente en el mac? (Sí, soy consciente de que en los sistemas Unixy no hay "tiempo de creación.")


resultado de ejecutar el guión de Chris Johnsen:

[email protected]:~$ /usr/bin/python timetest.py tempfile 5 
initial: 
(1269631281.0, 1269631281.0, 1269631281.0, 1269631281, 1269631281, 1269631281) 

test: (1000000000, 1000000000) 
(1000000000.0, 1000000000.0, 1269631281.0, 1000000000, 1000000000, 1269631281) 
(1269631281.0, 1000000000.0, 1269631281.0, 1269631281, 1000000000, 1269631281) 

test: (1000000000, 1500000000) 
(1000000000.0, 1500000000.0, 1269631286.0, 1000000000, 1500000000, 1269631286) 
(1269631286.0, 1500000000.0, 1269631286.0, 1269631286, 1500000000, 1269631286) 

test: (1500000000, 1000000000) 
(1500000000.0, 1000000000.0, 1269631291.0, 1500000000, 1000000000, 1269631291) 
(1269631291.0, 1000000000.0, 1269631291.0, 1269631291, 1000000000, 1269631291) 

test: (1500000000, 1500000000) 
(1500000000.0, 1500000000.0, 1269631296.0, 1500000000, 1500000000, 1269631296) 
(1269631296.0, 1500000000.0, 1269631296.0, 1269631296, 1500000000, 1269631296) 

Al final del ejercicio, el 'creado 'La fecha como visible en el buscador es el 9/8/01 y la fecha' modificada 'es el 7/13/17. (La fecha de acceso, gracias probablemente a los reflectores que sugieres y a la que he leído, es aproximadamente "ahora"). Las fechas creadas y modificadas visibles en el buscador aún no tienen sentido.

+0

En una secuencia de comandos de copia de seguridad de python que escribí en osx, noté que solo puedo confiar en que el mtime sea coherente también. – snies

+1

ctime no es "hora creada", es "hora de cambio de inodo" (consulte la página de manual de stat (2)). Un "tiempo de creación" se almacena en Mac OS X, pero no lo utilizan generalmente los programas POSIX, ya que no es portátil. –

+0

@Chris: Lo sé. Cuando digo tiempo "creado", me refiero al tiempo "creado" según lo informado por el Buscador. –

Respuesta

2

POSIX atime, mtime, ctime

Podría ayudar si se incluye un guión completo y sus resultados reales y esperados en lugar de los fragmentos REPL.

import sys, os, stat, time 

def get_times(p): 
    s = os.stat(p) 
    return ( 
     os.path.getatime(p), 
     os.path.getmtime(p), 
     os.path.getctime(p), 
     s[stat.ST_ATIME], 
     s[stat.ST_MTIME], 
     s[stat.ST_CTIME], 
    ) 

def main(p, delay=1): 
    delay = float(delay) 
    (a,b) = (1000000000, 1500000000) 

    open(p,'w').close() 

    print 'initial:' 
    print get_times(p) 

    for t in [ (a,a), (a,b), (b,a), (b,b) ]: 
     print 
     print 'test:', t 
     os.utime(p,t) 
     print get_times(p) 
     time.sleep(delay) 
     print get_times(p) 

main(*sys.argv[1:]) 

consigo esto en mi sistema con 10,4 cd "$HOME" && python test.py tempfile 5 (sistema por defecto de Python 2.3.6 y 2.6.4 de Python DarwinPorts ambos dan el mismo resultado (dejando de lado los tiempos iniciales y ctime, por supuesto)):

% python /tmp/test.py tempfile 5 
initial: 
(1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881) 

test: (1000000000, 1000000000) 
(1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881) 
(1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881) 

test: (1000000000, 1500000000) 
(1000000000.0, 1500000000.0, 1269629886.0, 1000000000, 1500000000, 1269629886) 
(1000000000.0, 1500000000.0, 1269629886.0, 1000000000, 1500000000, 1269629886) 

test: (1500000000, 1000000000) 
(1500000000.0, 1000000000.0, 1269629891.0, 1500000000, 1000000000, 1269629891) 
(1500000000.0, 1000000000.0, 1269629891.0, 1500000000, 1000000000, 1269629891) 

test: (1500000000, 1500000000) 
(1500000000.0, 1500000000.0, 1269629896.0, 1500000000, 1500000000, 1269629896) 
(1500000000.0, 1500000000.0, 1269629896.0, 1500000000, 1500000000, 1269629896) 

Eso parece razonable. Me pregunto qué obtienes.

He oído que Spotlight a veces puede restablecer agresivamente atime debido a la nueva indexación de archivos modificados. No esperaría que vuelva a indexar un archivo que solo se haya sometido a utime()/utimes(), pero supongo que es posible. Para eliminar Spotlight como una posible complicación, use un archivo en una ubicación que no esté indexada por Spotlight (por ejemplo,/tmp/testfile).

Fecha de creación en Buscador

(que se muestra como “Creación:” en Obtener información en las ventanas de Finder)

Si tiene instaladas las herramientas de desarrollo, puede utilizar /Developer/Tools/GetFileInfo para ver el HFS fechaCreacion. He añadido las siguientes líneas después de cada línea de print get_times(p):

sys.stdout.flush() 
os.system('/Developer/Tools/GetFileInfo ' + p) 

También ha cambiado la iteración para que coincida con su descripción inicial ([ (a,b), (a,a), (b,a), (b,b) ]).

El resultado ahora se ve así:

% rm /tmp/tempfile; python /tmp/test.py /tmp/tempfile 1 
initial: 
(1269636574.0, 1269636574.0, 1269636574.0, 1269636574, 1269636574, 1269636574) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 03/26/2010 15:49:34 
modified: 03/26/2010 15:49:34 

test: (1000000000, 1500000000) 
(1000000000.0, 1500000000.0, 1269636574.0, 1000000000, 1500000000, 1269636574) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 03/26/2010 15:49:34 
modified: 07/13/2017 21:40:00 
(1000000000.0, 1500000000.0, 1269636574.0, 1000000000, 1500000000, 1269636574) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 03/26/2010 15:49:34 
modified: 07/13/2017 21:40:00 

test: (1000000000, 1000000000) 
(1000000000.0, 1000000000.0, 1269636576.0, 1000000000, 1000000000, 1269636576) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 09/08/2001 20:46:40 
modified: 09/08/2001 20:46:40 
(1000000000.0, 1000000000.0, 1269636576.0, 1000000000, 1000000000, 1269636576) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 09/08/2001 20:46:40 
modified: 09/08/2001 20:46:40 

test: (1500000000, 1000000000) 
(1500000000.0, 1000000000.0, 1269636577.0, 1500000000, 1000000000, 1269636577) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 09/08/2001 20:46:40 
modified: 09/08/2001 20:46:40 
(1500000000.0, 1000000000.0, 1269636577.0, 1500000000, 1000000000, 1269636577) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 09/08/2001 20:46:40 
modified: 09/08/2001 20:46:40 

test: (1500000000, 1500000000) 
(1500000000.0, 1500000000.0, 1269636578.0, 1500000000, 1500000000, 1269636578) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 09/08/2001 20:46:40 
modified: 07/13/2017 21:40:00 
(1500000000.0, 1500000000.0, 1269636578.0, 1500000000, 1500000000, 1269636578) 
file: "/private/tmp/tempfile" 
type: "" 
creator: "" 
attributes: avbstclinmedz 
created: 09/08/2001 20:46:40 
modified: 07/13/2017 21:40:00 

Esto parece ser consistente con las observaciones de su ventana Obtener información en Buscador. Mi interpretación (confirmada por otros experimentos) es que HFS creationDate se actualiza por utime, pero solo va hacia atrás (nunca hacia adelante). Si desea actualizar HFS creationDate a un valor más nuevo, entonces probablemente tendrá que usar una API específica de Mac para hacerlo.

Otra nota: es posible que tenga que cambiar un poco las ventanas para obtener la ventana Obtener información para actualizar. En mi sistema, su pantalla no se actualiza automáticamente a menos que cambie las ventanas hacia o desde la ventana Obtener información.

0

Mac OS mantiene atributos adicionales que no se asignan a posix.

  • CreateDate
  • contentModDate
  • attributeModDate
  • fechaacceso
  • backupDate

Usted solía ser capaz de acceder a ellos a través del módulo macfs viejos, que fue hace mucho tiempo desfasado y en su del módulo de carbono, que en gran medida no está documentado, y ahora también está en desuso. Creo que Carbon.File y Carbon.Folder tienen lo que necesitas. (No sigo Mac suficiente para saber lo que el plan actual es que estas características. Quizás carbono es simplemente ser retirado del stdlib, y continuará por sí mismo.)

Tal vez un comentario detallando lo que Lo que está buscando es ayudar, en lugar de un voto a la baja

No estoy exactamente seguro de qué otra consistencia usted espera. Python está utilizando una API posix, y las herramientas de Apple están usando la API de Apple. Cada uno parece ser internamente consistente, pero pueden diferir entre sí.

  • attributeModDate se asigna a ctime.
  • createDate es lo que Finder muestra para "creado"
  • Si cambia mtime a anterior a createDate, la api mac del sistema de archivos cambiará el createDate para que coincida; que previene la inconsistencia de una aparente modificación antes de una creación. Esto aborda el único comportamiento incoherente que puedo obtener de su ejemplo anterior.
+0

En su mayor parte, esos atributos HFS + se asignan a los atributos POSIX stat() equivalentes. contentModDate es lo mismo que mtime, attributeModDate es lo mismo que ctime, y accessDate es lo mismo que atime. – mipadi

+0

@mipadi - es posible que haya comentado antes de que se publicara mi edición, pero sí lo sé;) Desafortunadamente, el OP está buscando createDate a través del Finder, que no está asignado a un atributo POSIX – JimB

Cuestiones relacionadas