2009-11-27 4 views
26

Sous Unix, existe-t-il une commande permettant d'afficher l'heure de modification d'un fichier, précise par rapport à la seconde?Temps de modification du fichier (secondes) sous Unix

Sur Linux, cela se fait facilement avec un "stat -c% y", qui renvoie quelque chose comme 2009-11-27 11:36:06.000000000 +0100. Je n'ai trouvé aucun équivalent sur Unix.

+1

Appartient à SuperUser – Yacoby

+6

Ceci est clairement à des fins de développement de script, ce qui à mon avis signifie clairement qu'il appartient ici. – Benj

+3

J'utilise un bureau et une chaise à des fins de développement, cela compte-t-il aussi? – skaffman

Répondre

7

Selon la page de manuel sur mon Mac (qui a la version standard BSD de stat), vous pouvez obtenir la version de temps époque de la modification en quelques secondes:

stat -f %m /etc/passwd 

Ou si vous voulez imprimer que en heures: minutes: secondes vous pouvez le faire:

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

Ma question est essentiellement: comment le faire sans commande de stat! – ExpertNoob1

+0

La plupart des versions Unix ont des commandes de style BSD (dont stat est une) Linux a des commandes de style GNU (qui a une stat avec des commutateurs différents). Si votre saveur Unix n'a pas de statistiques du tout, vous feriez mieux de nous dire quel Unix vous utilisez. – Benj

+0

HP UX 11.11. Donne mon argent! – ExpertNoob1

2

Pour toute personne face à la même question, je trouve pas de solution (sur HP-UX 11i de toute façon). Fini le codage d'un "ls -lh" personnalisé pour mes besoins. Il est pas difficile .. Prints quelque chose comme:

- 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/ 

Ici, il 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(), vous avez toutes les fonctionnalités d'appel système lstat(), vous pouvez personnaliser ceci à votre vœux.

Soyez bien.

1

Sous AIX la commande ISTAT fait ceci:

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

La commande find est une bonne source pour toutes sortes d'informations de fichiers, y compris le temps de modification à la seconde:

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

Le premier argument peut être un fichier. Le paramètre maxdepth empêche la recherche si un nom de répertoire est donné. Le% T lui demande d'imprimer l'heure de la dernière modification.

Certains systèmes interprètent% TS comme des secondes à virgule flottante (par exemple 36.8342610). Si vous voulez des secondes fractionnaires, utilisez "% TS" au lieu de "% .2TS", mais vous ne verrez pas de secondes fractionnaires sur chaque système.

+0

Cela est spécifique à l'implémentation GNU de 'find'. –

+0

trouver: absence de conjonction –

19

Je trouve ceci:

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

qui exporte quelque chose comme ceci:

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

Nice find! Ne fonctionne pas dans Solaris. Peut être une chose Linux seulement. –

+0

A fonctionné correctement sur SmartOS, qui est livré avec un GNU ls. Donc, si vous en avez besoin sur Solaris, vous devriez pouvoir obtenir le même résultat en utilisant la version GNU de ls. – noamik

+0

Cela est spécifique à l'implémentation GNU de 'ls'. FreeBSD 'ls' a une option' -D' pour cela. –

1

Si vous utilisez HP-UX:

Ok, disons que le nom du le fichier est "indésirable". Sur HP-UX, vous pouvez faire:

perl -e '@ d = heure locale ((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] 'indésirable

Et oui, perl est livré avec HP-UX. C'est dans/usr/contrib. Mais vous pouvez avoir une version plus récente dans/usr/local ou/opt.

Source: Perderabo

1

Aujourd'hui, j'ai rencontré le même problème sur une ancienne version de HP-UX. Le programme statistique ne faisait pas partie de l'installation. (La version C uniquement)

La solution la plus rapide pour moi était d'utiliser un outil tel que le transfert de fichiers Tectia sur mon ordinateur portable, sans effectuer de copie. Il convertit l'heure de la dernière modification pour HP-UX et fournit des dates et des heures pour tous les fichiers une fois que vous vous êtes connecté à UNIX.

Peut-être cela fonctionne avec d'autres outils de transfert de fichiers graphiques similaires, mais je n'ai pas encore essayé.

7

Ce qui suit vous donne de dernière modification en secondes depuis Epoch:

stat -c%Y <file> 
+0

Cela est spécifique à l'implémentation GNU de 'stat'. D'autres implémentations 'stat' incluent (dans l'ordre chronologique): IRIX stat, zsh stat builtin, BSD stat. –

2

Sous Mac OS X (testé sur 10.10.5 Yosemite à travers 10.12.4 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

Essayez une perl one-liner:

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 fonctionne que si -le vous avez besoin que HH: MM: SS