2009-11-27 78 views
26

在Unix上,是否有命令显示文件的修改时间,精确到秒?Unix上的文件修改时间(秒)

在Linux上,这很容易用“stat -c%y”完成,它返回类似2009-11-27 11:36:06.000000000 +0100的东西。我在Unix上找不到任何等价物。

+1

属于超级用户 – Yacoby

+6

这显然是脚本开发的目的,在我看来这意味着它显然属于这里。 – Benj

+3

为了发展目的我使用桌子和椅子,这也算得上吗? – skaffman

回答

7

根据我的Mac上的man page(具有BSD标准版统计的),你可以得到改变的信号出现时间的版本以秒为:

stat -f %m /etc/passwd 

或者,如果你想打印出小时:分钟:秒,你可以这样做:

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

我的问题基本上是:如何在没有stat命令的情况下做到这一点! – ExpertNoob1

+0

大多数Unix风格都有BSD风格的命令(其中stat是一个)Linux有GNU风格的命令(它具有不同开关的属性)。如果你的Unix风格根本没有统计信息,你最好告诉我们你正在使用哪个Unix。 – Benj

+0

HP UX 11.11。给我钱! – ExpertNoob1

2

对于任何面临着同样的问题,我没有发现任何解决方案(在HP-UX 11i的反正)。 完成了为我的需求编码个性化的“ls -lh”。这并不难.. 版画一样的东西:

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

这就是:

#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; 
} 

在printFSObjectInfo()你有LSTAT()系统调用的全部功能,可以自定义这个你祝愿。

很好。

1

在AIX上,国家统计局的命令做到这一点:

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

find命令是所有类型的文件,一个很好的信息源,包括修改时间到第二个:

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

第一个参数可以是一个文件。 maxdepth阻止搜索是否给出目录名称。 %T指示它打印上次修改时间。

某些系统将%TS解释为浮点秒(例如36.8342610)。如果您希望小数秒使用“%TS”而不是“%.2TS”,但是您可能在每个系统上看不到小数秒。

+0

这对于'find'的GNU实现是特定的。 –

+0

找不到:missing missing –

19

我发现这一点:

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

其中出口是这样的:

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

不错的发现!在Solaris中不起作用。可能只是一个Linux的东西。 –

+0

适用于SmartOS,它与GNU ls一起发货。所以如果你在Solaris上需要它,你应该能够通过使用GNU版本的ls来获得相同的结果。 – noamik

+0

这是'ls'的GNU实现特有的。 FreeBSD的'ls'有一个'-D'选项。 –

1

如果您正在使用HP-UX:

好吧,让我们说的名字文件是“垃圾”。在HP-UX上,您可以执行以下操作:

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]'垃圾

是的,perl附带了HP-UX。它在/ usr/contrib中。但是你可能在/ usr/local或/ opt中有更新的版本。

来源:Perderabo

1

今天,我遇到了一个老版本的HP-UX的同样的问题。统计程序不是安装的一部分。 (只是C版本)

对我来说,最快的解决方案是使用我的笔记本电脑上运行的Tectia文件传输工具,但实际上没有进行任何复制,它将从HP-UX转换为您的上次修改时间,为登录到UNIX后的所有文件提供日期和时间。

这可能适用于其他类似的基于图形的文件传输工具,但我还没有尝试过。

7

下面给你纪元以来的秒数最后修改时间:

stat -c%Y <file> 
+0

这对于'stat'的GNU实现是特定的。其他'stat'实现包括(按时间顺序):IRIX stat,zsh stat builtin,BSD stat。 –

2

在Mac OS X(10.10.5上约塞米蒂测试直通10.12.4塞拉利昂):

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

尝试Perl的一个班轮:

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的作品,如果你只需要HH:MM: SS