2010-03-18 14 views
8

Tôi muốn sao chép đầu ra của ls --full-time từ tập lệnh Perl để tránh chi phí gọi ls vài nghìn lần. Tôi đã hy vọng sử dụng chức năng stat và lấy tất cả thông tin từ đó. Tuy nhiên, dấu thời gian trong đầu ra ls sử dụng đồng hồ có độ phân giải cao để nó bao gồm số nano giây (theo tài liệu GNU, điều này là do - toàn bộ thời gian tương đương với --format=long --time-style=full-iso và kiểu toàn thời gian iso bao gồm các nano giây).Làm thế nào tôi có thể nhận được mtime cao res cho một liên kết tượng trưng trong Perl?

Tôi đã xem mô-đun Time::HiRes, ghi đè hàm stat chuẩn với hàm trả về atime/mtime/ctime dưới dạng số dấu phẩy động, nhưng không ghi đè cho lstat. Đây là một vấn đề, bởi vì việc gọi stat trên một liên kết tượng trưng trả về thông tin cho tệp được liên kết, không phải cho chính liên kết đó.

Vì vậy, câu hỏi của tôi là điều này - nơi tôi có thể tìm thấy một phiên bản của lstat trả về atime/mtime/ctime trong cùng một cách như Thời gian :: HiRes :: stat? Nếu không, đó là một cách khác để có được modtime cho một symlink ở độ phân giải cao (không phải là ls).

+2

Bạn có cần giải pháp di động hoặc chỉ có một hệ điều hành đích không? – mob

Trả lời

3

Đặt cược tốt nhất của bạn là yêu cầu lstat để được thêm vào Time::HiRes. Trong thực tế, bạn có thể có thể làm điều đó cho mình. Tôi muốn đặt cược rằng tất cả các bạn cần làm là sao chép các chức năng bắt đầu

void 
stat(...) 

trong HiRes.xs, thay đổi stat(...)-lstat(...) & OP_STAT để OP_LSTAT, thêm lstat để @EXPORT_OK trong HiRes.pm, và biên dịch lại. Sau đó gửi bản vá để người khác có thể hưởng lợi.

+0

Thay đổi OP_STAT thành OP_LSTAT sẽ không hoạt động như PL_ppaddr [OP_LSTAT] giống với PL_ppaddr [OP_STAT] vì Perl_pp_lstat được thực hiện bởi Perl_pp_stat ... Nhưng +1 cho thực tế là câu trả lời của bạn đã cho tôi một ý tưởng về cách tiếp cận vấn đề . –

4

Nếu bạn sẵn sàng để sử dụng Inline :: C, điều này sẽ làm việc với Linux gần đây

#!/usr/bin/perl 

use strict; 
use warnings; 

use Inline C => <<'EOC'; 

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

long mtime_nsec(char* fname) 
{ 
    struct stat st; 
    if (-1 == lstat(fname, &st)) 
     return -1; 
    return (long)st.st_mtim.tv_nsec; 
} 
EOC 

print mtime_nsec($ARGV[0]); 
2

Những thay đổi sau đây làm việc. Về cơ bản, điều này có chứa các thay đổi đối với cả mô-đun HiRes.pm cũng như tệp xs.

Trong HiRes.pm

sub lstat { 
    my @lstatvalues = CORE::lstat(shift); 
    my @nanosecvalues = Time::HiRes::lstatimplementation($lstatvalues[8], $lstatvalues[9], $lstatvalues[10]); 
    ($lstatvalues[8], $lstatvalues[9], $lstatvalues[10]) = ($nanosecvalues[0], $nanosecvalues[1], $nanosecvalues[2]); 
    return @lstatvalues; 
} 

Cũng thêm lstat để @EXPORT_OK danh sách.

Trong HiRes.xs

void 
lstatimplementation(...) 
PPCODE: 
    UV atime = SvUV(ST(0)); 
    UV mtime = SvUV(ST(1)); 
    UV ctime = SvUV(ST(2)); 
    UV atime_nsec; 
    UV mtime_nsec; 
    UV ctime_nsec; 
    hrstatns(atime, mtime, ctime, 
     &atime_nsec, &mtime_nsec, &ctime_nsec); 
    if (atime_nsec) 
    XPUSHs(sv_2mortal(newSVnv(atime + 1e-9 * (NV) atime_nsec))); 
    if (mtime_nsec) 
    XPUSHs(sv_2mortal(newSVnv(mtime + 1e-9 * (NV) mtime_nsec))); 
    if (ctime_nsec) 
    XPUSHs(sv_2mortal(newSVnv(ctime + 1e-9 * (NV) ctime_nsec))); 
+0

Bạn đã gửi bản vá cho [RT] chưa (https://rt.cpan.org/Public/Dist/Display.html?Name=Time-HiRes)? –

+0

@BradGilbert - Chưa. Tôi cũng tìm thấy một cách khác để hoàn thành thay đổi này hoàn toàn trong tệp xs. vẫn quyết định lựa chọn nào tốt hơn –

1

Đối với hồ sơ, lstat đã được thêm vào Thời thuê phiên bản 1,9726 vào tháng năm 2013.

Xem https://rt.cpan.org/Public/Bug/Display.html?id=83356 để biết chi tiết.

Tuy nhiên, vẫn là 1.9725 được bao gồm trong phiên bản ổn định mới nhất của perl kể từ 2014-01-31 (5.18.2). Mặc dù vậy, nó đã bị đụng đến 1.9726 trong phiên bản phát triển trong 5.19.3.

Lưu ý rằng (theo số perl 5.19.8), bất kể Time::HiRes 's lstatsử dụng hay không, perl của -M/-A/-C vẫn không làm granularity phụ thứ hai (các file theo thời gian trong cùng một thứ hai sẽ được hiển thị như là có cùng độ tuổi), vì vậy bạn vẫn không thể làm những việc như sort {-M $a <=> -M $b} @files để sắp xếp tệp theo thời gian sửa đổi.