2009-11-27 15 views
26

En Unix, ¿existe un comando para mostrar la hora de modificación de un archivo, precisa a la segunda?Tiempo de modificación del archivo (segundos) en Unix

En Linux esto se hace fácilmente con un "stat -c% y", que devuelve algo así como 2009-11-27 11:36:06.000000000 +0100. No encontré ningún equivalente en Unix.

+1

Pertenece a SuperUser – Yacoby

+6

Esto es claramente para el desarrollo de guiones, lo que en mi opinión significa que claramente pertenece aquí. – Benj

+3

Uso un escritorio y una silla con fines de desarrollo, ¿eso también cuenta? – skaffman

Respuesta

7

De acuerdo con la página del manual en mi Mac (que tiene la versión estándar BSD de stat) se puede obtener la versión de tiempo época de la modificación en cuestión de segundos con:

stat -f %m /etc/passwd 

O si desea imprimir ese en horas: minutos: segundos usted puede hacer esto:

perl -e "print scalar(localtime(`stat -f %m /etc/passwd`))" 
+1

Mi pregunta es básicamente: cómo hacerlo sin comando stat! – ExpertNoob1

+0

La mayoría de los sabores de Unix tienen comandos de estilo BSD (de los cuales stat es uno) Linux tiene comandos de estilo GNU (que tiene una estadística con diferentes interruptores). Si su sabor de Unix no tiene ninguna estadística, será mejor que nos diga qué Unix está usando. – Benj

+0

HP UX 11.11. ¡Dame mi dinero! – ExpertNoob1

2

Para cualquier persona que enfrenta el mismo problema, no he encontrado ninguna solución (en HP-UX 11i de todos modos). Terminé la codificación de un "ls -lh" personalizado para mis necesidades. No es tan difícil .. imprime algo como:

- 664 rw-/rw-/r-- 1L expertNoob adm 8.37 kB 2010.08.24 12:11:15 findf1.c 
d 775 rwx/rwx/r-x 2L expertNoob adm  96 B 2010.08.24 15:17:37 tmp/ 
- 775 rwx/rwx/r-x 1L expertNoob adm  16 kB 2010.08.24 12:35:30 findf1 
- 775 rwx/rwx/r-x 1L expertNoob adm  24 kB 2010.09.14 19:45:20 dir_info 
- 444 r--/r--/r-- 1L expertNoob adm 9.01 kB 2010.09.01 11:23:41 getopt.c 
- 664 rw-/rw-/r-- 1L expertNoob adm 6.86 kB 2010.09.01 11:24:47 getopt.o 
- 664 rw-/rw-/r-- 1L expertNoob adm 6.93 kB 2010.09.14 19:37:44 findf1.o 
l 775 rwx/rwx/r-x 1L expertNoob adm  6 B 2010.10.06 17:09:01 test1 -> test.c 
- 664 rw-/rw-/r-- 1L expertNoob adm 534 B 2009.03.26 15:34:23 > test.c 
d 755 rwx/r-x/r-x 25L expertNoob adm  8 kB 2009.05.20 15:36:23 zip30/ 

aquí está:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/errno.h> 
#include <dirent.h> 
#include <pwd.h> 
#include <grp.h> 
#include <time.h> 
#include <locale.h> 
#include <langinfo.h> 
#include <stdio.h> 
//#include <stdint.h> 
#include <limits.h> // PATH_MAX 
#include <stdarg.h> 
#include "getopt.h" 

static short START_VSNBUFF=16; 
// This is bformat from Better String library (bstrlib), customized 
int strformat (char ** str, const char * fmt, ...) { 

    va_list arglist; 
    char * buff; 
    int n, r; 

    /* Since the length is not determinable beforehand, a search is 
     performed using the truncating "vsnprintf" call (to avoid buffer 
     overflows) on increasing potential sizes for the output result. */ 

    if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; 
    if (NULL == (buff = (char *) malloc((n + 2)*sizeof(char)))) { 
     n = 1; 
     if (NULL == (buff = (char *) malloc((n + 2)*sizeof(char)))) { 
      fprintf(stderr, "strformat: not enough memory to format string\n"); 
      return -1; 
     } 
    } 

    for (;;) { 
     va_start (arglist, fmt); 
     r = vsnprintf (buff, n + 1, fmt, arglist); // n+1 chars: buff[0]..buff[n], n chars from arglist: buff[n]='\0' 
     va_end (arglist); 

     buff[n] = (unsigned char) '\0'; // doesn't hurt, especially strlen! 

     if (strlen(buff) < n) break; 

     if (r > n) n = r; else n += n; 

     if (NULL == (buff = (char *) realloc(buff, (n + 2)*sizeof(char)))) { 
      free(buff); 
      fprintf(stderr, "strformat: not enough memory to format string\n"); 
      return -1; 
     } 
    } 

    if(NULL != *str) free(*str); 
    *str = buff; 
    return 0; 
} 

int printFSObjectInfo(const char * path, const char * name) { 

    struct stat statbuf; 

    struct passwd *pwd; 
    struct group *grp; 
    struct tm  *tm; 
    char   datestring[256]; 
    char   *type = "? "; 
    char   *fbuf = NULL; 

    double   size = 0; 
    const char  *units[] = {"B ", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; 
    int   i = 0; 

    char owner[] = "---", group[] = "---", others[] = "---"; 


    /* Get entry's information. */ 
    if (-1 == lstat(path, &statbuf)) { 
     fprintf(stderr, "printFSObjectInfo: error: can't stat %s\n", path); 
     if(0 == strformat(&fbuf, "lstat() said: %s", path)) { perror(fbuf); return -1; } 
    } 

    // File type 
    if(S_ISREG(statbuf.st_mode)) type = "-"; // regular file 
    if(S_ISDIR(statbuf.st_mode)) {   // directory 
     type="d"; 
     if(S_ISCDF(statbuf.st_mode)) type = "hd"; // hidden dir 
    } 
    if(S_ISBLK(statbuf.st_mode)) type = "b"; // block special 
    if(S_ISCHR(statbuf.st_mode)) type = "c"; // character special 
    if(S_ISFIFO(statbuf.st_mode)) type = "f"; // pipe or FIFO 
    if(S_ISLNK(statbuf.st_mode)) type = "l"; // symbolic link 
    if(S_ISSOCK(statbuf.st_mode)) type = "s"; // socket 
    if(S_ISNWK(statbuf.st_mode)) type = "n"; // network special 
    printf("%2s ", type); 

    /* Print out type, permissions, and number of links. */ 
    //printf("%10.10s", sperm (statbuf.st_mode)); 
    if(S_IRUSR & statbuf.st_mode) owner[0] = 'r'; 
    if(S_IWUSR & statbuf.st_mode) owner[1] = 'w'; 
    if(S_IXUSR & statbuf.st_mode) owner[2] = 'x'; 

    if(S_IRGRP & statbuf.st_mode) group[0] = 'r'; 
    if(S_IWGRP & statbuf.st_mode) group[1] = 'w'; 
    if(S_IXGRP & statbuf.st_mode) group[2] = 'x'; 

    if(S_IROTH & statbuf.st_mode) others[0] = 'r'; 
    if(S_IWOTH & statbuf.st_mode) others[1] = 'w'; 
    if(S_IXOTH & statbuf.st_mode) others[2] = 'x'; 

    //printf("\n%o\n", statbuf.st_mode); 
    printf("%3o %s/%s/%s ", 0777 & statbuf.st_mode, owner, group, others); 

    printf("%4dL", statbuf.st_nlink); 

    /* Print out owner's name if it is found using getpwuid(). */ 
    if ((pwd = getpwuid(statbuf.st_uid)) != NULL) 
     printf(" %-8.8s", pwd->pw_name); 
    else 
     printf(" %-8d", statbuf.st_uid); 

    /* Print out group name if it is found using getgrgid(). */ 
    if ((grp = getgrgid(statbuf.st_gid)) != NULL) 
     printf(" %-8.8s", grp->gr_name); 
    else 
     printf(" %-8d", statbuf.st_gid); 

    /* Print size of file. */ 
    //printf(" %9d", (int)statbuf.st_size); 
    i = 0; 
    size = (double) statbuf.st_size; 
    while (size >= 1024) { 
     size /= 1024; 
     i++; 
    } 
    if(0 == (double)(size - (long) size)) 
     printf("%7d %-2s", (long)size, units[i]); 
    else printf("%7.2f %-2s", size, units[i]); 

    tm = localtime(&statbuf.st_mtime); 

    /* Get localized date string. */ 
    strftime(datestring, sizeof(datestring), "%Y.%m.%d %T", tm); // nl_langinfo(D_T_FMT) 

    if (0 == strcmp(name, "\n")) 
     printf(" %s > %s", datestring, path); 
    else { 
     if(0 == strcmp(type, "d")) printf(" %s %s/", datestring, name); 
     else       printf(" %s %s", datestring, name); 
    } 

    if(0 == strcmp(type, "l")) { 
     char buf[1+PATH_MAX]; 
     if(-1 == readlink(path, buf, (1+PATH_MAX))) { 
      fprintf(stderr, "printFSObjectInfo: error: can't read symbolic link %s\n", path); 
      if(0 == strformat(&fbuf, "readlink() said: %s:", path)) { perror(fbuf); return -2; } 
     } 
     else { 
      lstat(buf, &statbuf); // want errno, a symlink may point to non-existing object 
      if(errno == ENOENT) printf(" -> %s [!no such file!]\n", buf); 
      else { 
       printf(" -> %s\n", buf); 
       if (0 != strcmp(name, "\n")) printFSObjectInfo(buf, "\n"); 
      } 
     } 
    } 
    else printf("\n"); 

    return 0; 
} 

int main(int argc, char **argv) { 

    struct dirent *dp; 
    struct stat statbuf; 

    char   *path = NULL; //[1+PATH_MAX]; 
    char   *fbuf = NULL; 
    char   *pathArg = NULL; 

    if(argc == 1 || 0 == strlen(argv[1])) pathArg = "."; 
    else pathArg = argv[1]; 

    if (lstat(pathArg, &statbuf) == -1) { 
     printf("%s: error: can't stat %s\n", argv[0], pathArg); 
     if(0 == strformat(&fbuf, "stat() said: %s", pathArg)) perror(fbuf); 
     exit(2); 
    } 

if(S_ISDIR(statbuf.st_mode)) { 
    DIR *dir = opendir(pathArg); 
    if(NULL == dir) { 
     fprintf(stderr, "%s: error: can't open %s\n", argv[0], pathArg); 
     if(0 != strformat(&fbuf, "opendir() said: %s", pathArg)) exit(5); 
     perror(fbuf); 
     exit(4); 
    } 

    /* Loop through directory entries. */ 
    while ((dp = readdir(dir)) != NULL) { 

     if(0!= strformat(&path, "%s/%s", pathArg, dp->d_name)) continue; 

     printFSObjectInfo(path, dp->d_name); 
    } 
    closedir(dir); 
} else printFSObjectInfo(pathArg, pathArg); 

    return 0; 
} 

En printFSObjectInfo() que toda la funcionalidad de lstat llamada al sistema(), puede personalizar esto para su deseos.

Be well.

1

En AIX el comando istat hace esto:

machine:~/support> istat ../core 
Inode 30034 on device 32/3  File 
Protection: rw-rw-r-- 
Owner: 500(group)    Group: 500(user) 
Link count: 1   Length 10787748 bytes 

Last updated: Wed Feb 22 13:54:28 2012 
Last modified: Wed Feb 22 13:54:28 2012 
Last accessed: Wed Feb 22 19:58:10 2012 
5

El comando find es una buena fuente para todo tipo de información de archivo, incluyendo el tiempo de modificación a la segunda:

find /etc/passwd -maxdepth 0 -printf "%TY/%Tm/%Td %TH:%TM:%.2TS\n" 
2011/11/21 13:41:36 

El primer argumento puede ser un archivo El maxidepth evita la búsqueda si se da un nombre de directorio. El% T le indica que imprima la última modificación de tiempo.

Algunos sistemas interpretan% TS como segundos de coma flotante (por ejemplo, 36.8342610). Si desea fracciones de segundo, use "% TS" en lugar de "% .2TS", pero es posible que no vea fracciones de segundo en cada sistema.

+0

Eso es específico de la implementación GNU de 'find'. –

+0

encontrar: conjunción faltante –

19

encontré esto:

ls --time-style='+%d-%m-%Y %H:%M:%S' -l 

que exporta algo como esto:

root:~# ls --time-style='+%d-%m-%Y %H:%M:%S' -l 
total 0 
-rw-r--r-- 1 root root 0 16-04-2015 23:14:02 other-file.txt 
-rw-r--r-- 1 root root 0 16-04-2015 23:13:58 test.txt 
+0

¡Bonito hallazgo! No funciona en Solaris. Puede ser solo Linux. –

+0

Funcionó bien en SmartOS, que se envía con un GNU ls. Por lo tanto, si lo necesita en Solaris, debería poder obtener el mismo resultado utilizando la versión de GNU de ls. – noamik

+0

Eso es específico de la implementación GNU de 'ls'. FreeBSD 'ls' tiene una opción' -D' para eso. –

1

Si está utilizando HP-UX:

Ok vamos a decir que el nombre de la el archivo es "basura". En HP-UX puede hacer:

perl -e '@ d = localtime ((stat (shift)) [9]); printf "% 4d-% 02d-% 02d% 02d:% 02d:% 02d \ n", $ d [5] + 1900, $ d [4] + 1, $ d [3], $ d [2], $ d [1], $ d [0] 'basura

Y sí, Perl viene con HP-UX. Está en/usr/contrib. Pero puede tener una versión más reciente en/usr/local o/opt.

Fuente: Perderabo

1

Hoy me encontré con el mismo problema en una versión antigua de HP-UX. El programa de estadísticas no era parte de la instalación. (solo la versión C)

La solución más rápida para mí fue utilizar una herramienta como la transferencia de archivos Tectia en mi computadora portátil, sin hacer ninguna copia, convierte la hora de la última modificación para usted de HP-UX y proporciona fechas y horas para todos los archivos una vez que haya iniciado sesión en UNIX.

Posiblemente esto funciona con otras herramientas similares de transferencia de archivos basadas en gráficos, pero aún no lo he intentado.

7

A continuación se le da la última hora de modificación en segundos desde el Epoch:

stat -c%Y <file> 
+0

Esto es específico de la implementación de GNU de 'stat'. Otras implementaciones 'stat' incluyen (en orden cronológico): IRIX stat, zsh stat incorporado, BSD stat. –

2

En Mac OS X (probado en 10.10.5 10.12.4 Yosemite a través de la Sierra):

prompt> ls -lT 

total 0 
-rw-r--r-- 1 youruser staff 0 Sep 24 10:28:30 2015 my_file_1.txt 
-rw-r--r-- 1 youruser staff 0 Sep 24 10:28:35 2015 my_file_2.txt 
0

Prueba una perl de una sola línea:

perl -e '@d=localtime ((stat(shift))[9]); printf "%02d-%02d-%04d %02d:%02d:%02d\n", $d[3],$d[4]+1,$d[5]+1900,$d[2],$d[1],$d[0]' your_file_to_show_the_date_for.your_extension 
1

ls -LE funciona si sólo se necesita HH: MM: SS

Cuestiones relacionadas