lần cuối mở tập tin


94

Có thể lấy thời gian khi tệp được mở lần trước và sắp xếp tất cả các tệp trong một thư mục theo thời gian đó không?

Câu trả lời:


172

Điều này phụ thuộc vào chính xác những gì bạn có nghĩa là "mở", nhưng nói chung, có. Có ba dấu thời gian thường được ghi lại:

  • mtime- cập nhật khi nội dung tập tin thay đổi. Đây là thời gian tập tin "mặc định" trong hầu hết các trường hợp.
  • ctime- được cập nhật khi tệp hoặc siêu dữ liệu của nó (chủ sở hữu, quyền) thay đổi
  • atime - cập nhật khi tập tin được đọc

Vì vậy, nói chung, những gì bạn muốn thấy là atimemột tập tin. Bạn có thể có được điều đó với stathoặc với ls. Bạn có thể sử dụng ls -luđể làm điều này, mặc dù tôi thích sử dụng hơn ls -l --time=atime(nên được hỗ trợ trong hầu hết các bản phân phối Linux hiện đại) vì tôi không sử dụng nó thường xuyên và khi tôi có thể nhớ nó tốt hơn. Và để sắp xếp theo thời gian, thêm -tcờ vào ls. Vì vậy, có bạn đi.

Có một cảnh báo lớn, mặc dù. Cập nhật atime mỗi khi đọc tệp gây ra rất nhiều IO thường không cần thiết, làm chậm mọi thứ. Vì vậy, hầu hết các bản phân phối Linux hiện mặc định cho noatimetùy chọn gắn kết hệ thống tệp, về cơ bản sẽ giết chết các atimes hoặc khác relatime, chỉ cập nhật các atimes khi giới hạn đã vượt qua (thông thường một lần mỗi ngày) hoặc nếu tệp thực sự được sửa đổi kể từ lần đọc trước. Bạn có thể tìm thấy nếu các tùy chọn này được kích hoạt bằng cách chạy mountlệnh.

Ngoài ra, lưu ý rằng thời gian truy cập là bằng inode chứ không phải theo tên tệp, vì vậy nếu bạn có liên kết cứng, đọc từ một sẽ cập nhật tất cả các tên tham chiếu đến cùng một tệp.

Và, lưu ý rằng c không phải là "sáng tạo"; việc tạo không được theo dõi bởi các hệ thống tệp Unix / Linux, điều này có vẻ lạ nhưng thực sự có ý nghĩa bởi vì hệ thống tệp không có cách nào để biết liệu đó có phải là bản gốc hay không - có thể tệp đã được tạo bốn mươi năm trước và được sao chép ở đây. Và trên thực tế, nhiều trình soạn thảo tệp hoạt động bằng cách tạo các bản sao so với bản gốc. Nếu bạn cần thông tin đó, tốt nhất nên sử dụng hệ thống kiểm soát phiên bản như thế nào git.


9
Tôi sẽ cung cấp cho bạn nhiều hơn +1 nếu tôi có thể, chỉ đơn giản là không gọi ctime là "Thời gian sáng tạo".
jsbillings

2
Theo manpage núi, relatime không có gì để làm với giới hạn hàng ngày, nhưng chỉ nhìn vào atime tương đối để mtime và ctime. Nếu atime cũ hơn mtime hoặc ctime, atime được cập nhật. Nếu atime mới hơn cả hai, thì nó được để lại một mình. Mục đích của việc này là để duy trì mối quan hệ giữa atime và mtime / ctime, vì một số ứng dụng sử dụng thông tin đó, như mutt để xem liệu nó có đọc hộp thư của bạn kể từ khi nó được cập nhật lần cuối không.
jw013

1
@ jw013 Đây là trường hợp kể từ kernel 2.6.30. Đúng là một số bản phân phối cũ hơn có thể không có hành vi này. (Nhưng đối với các bản phân phối như Fedora, nó đã đúng ngay cả khi tôi viết phiên bản gốc của câu trả lời này ba năm trước.) Hãy tìm một mounttrang web cập nhật .
mattdm

1
lsrút ngắn thời gian theo mặc định đến độ chính xác hợp lý. Để xem thời gian chính xác đầy đủ người ta có thể sử dụng --full-time.
jlh

19

ls -ltu liệt kê tất cả các tập tin, hiển thị và sắp xếp theo thời gian truy cập.

Từ man ls:

-u     with -lt: sort by, and show, access time with -l: show access
       time and sort by name otherwise: sort by access time

4

Các findlệnh là tốt nhất cho việc này. Xem -ctime, -mtime-atimetùy chọn


3

Nếu danh sách của bạn dành cho tiêu dùng của con người, hãy sử dụng lsvới một trong các cờ sắp xếp ngày ( -tucho thời gian truy cập (đọc), chỉ -tđể sửa đổi (ghi) thời gian hoặc -tccho thời gian thay đổi inode). Xem câu trả lời của mattdm để biết thêm thông tin (đặc biệt là cảnh báo về -avà định nghĩa của -c).

Nếu điều này là để tiêu thụ chương trình, phân tích đầu ra lslà có vấn đề . Nếu hệ vỏ của bạn là zsh, lsdù sao bạn cũng không cần : zsh có vòng loại toàn cầu để sắp xếp các trận đấu bằng cách tăng thời gian truy cập ( *(Oa)), thay đổi inode ( *(Oc)) hoặc sửa đổi ( *(Om)). Một chữ thường osắp xếp theo tuổi tăng.

act_on_files_by_date *(Om)

Mặt khác, nếu bạn biết rằng tên tệp không chứa bất kỳ ký tự dòng mới hoặc không in được (trong ngôn ngữ hiện tại), thì bạn có thể làm một cái gì đó như

ls -t | while read -r name; do act_on_one_file "$name"; done
ls -t | xargs -I {} act_on_one_file {}

Nếu bạn muốn gọi một lệnh trên nhiều tệp cùng một lúc, bạn cần thiết lập thêm. Lưu ý rằng act_on_files_by_date $(ls -t)không hoạt động như thế này, vì tên tệp chứa ký tự đại diện hoặc khoảng trắng sẽ được mở rộng trong kết quả của việc thay thế lệnh. Đoạn mã sau hoạt động miễn là không có tên tệp nào chứa dòng mới hoặc ký tự không in được:

IFS='
'
set -f
act_on_files_by_date $(ls -t)
set +f
unset IFS

Nếu bạn muốn đối phó với các tên tệp tùy ý, bạn sẽ có một khoảng thời gian rất khó khăn mà không cần dùng đến các công cụ mạnh hơn so với trình bao tiêu chuẩn: zsh, perl, python

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.