2008-11-27 41 views
9

Bất cứ khi nào tôi liệt kê nội dung của một thư mục có chức năng như readdir, tên tệp được trả lại cũng bao gồm "." và "..". Tôi nghi ngờ rằng đây chỉ là các liên kết bình thường trong hệ thống tệp và do đó không thể phân biệt được với các tệp thực, nhưng tôi luôn phải lọc chúng ra vì chúng không phải là đối tượng thực trong thư mục tôi liệt kê. Có lý do chính đáng nào cho các chức năng như readdir để đưa chúng vào không? Một số hệ điều hành hoặc hệ thống tệp có chứa nhiều tên tệp ảo khác không? Có cách nào tốt hơn để lọc chúng ra ngoài khác hơn là so sánh chuỗi với "." và ".."?Tại sao danh sách thư mục chứa thư mục (.) Và thư mục mẹ (..) hiện tại?

Cập nhật: cảm ơn tất cả vì đã trả lời. Tôi cho rằng tôi luôn nghĩ rằng những thứ như ./ và ../ chỉ là những quy ước có thể được xử lý bằng cách tìm kiếm và thay thế. Tôi thấy nó hơi ngạc nhiên, mặc dù có lẽ hiệu quả hơn và minh bạch hơn, để chúng trở thành một phần của hệ thống tập tin.

Vẫn còn một câu hỏi: kể từ đó. và .. là tên tùy ý cho các liên kết này, có hệ thống tệp nào sử dụng các hệ thống khác không?

Trả lời

11

... thực sự là liên kết cứng trong hệ thống tệp. Chúng là cần thiết để bạn có thể chỉ định đường dẫn tương đối, dựa trên một số đường dẫn tham chiếu (xem xét "../sibling/file.txt"). Vì các liên kết cứng này thực sự tồn tại trong hệ thống tập tin, điều này có ý nghĩa đối với readdir để cho bạn biết về chúng. (thực tế, thuật ngữ hard link chỉ có nghĩa là một số tên không thể phân biệt được với thư mục thực tế được đề cập: cả hai đều trỏ đến cùng một số inode trong hệ thống tệp).

Cách tốt nhất là chỉ strcmp và bỏ qua chúng, nếu bạn không muốn liệt kê chúng.

3

Một lý do là nếu không có chúng thì không có cách nào để vào thư mục mẹ. Hoặc có được một xử lý vào thư mục hiện hành.

Nếu không có họ, chúng tôi không thể làm những việc như:

./run_this 

Thật vậy, chúng ta không thể thêm '' với $ PATH, nghĩa là chúng tôi không thể thực thi các tệp chưa có trong đường dẫn.

+0

Trên Windows,. dường như là một phần của PATH ngầm, nghĩa là bạn có thể chỉ cần gõ run_this. Được sử dụng để điều này, tôi luôn luôn tìm thấy nhấn mạnh trên tiền tố ./ một chút khó chịu khi sử dụng Linux, mặc dù tôi hiểu giá trị của nó cho an ninh. – Lemming

+0

Tôi đã không thực sự nghĩ nhiều về những ràng buộc về bảo mật cho đến khi nó được giải thích cho tôi vào đầu năm nay. Người dùng khó chịu có thể có một lệnh trong thư mục của cô ấy được gọi là ls, một quản trị viên, khi điều hướng tới thư mục đó, có thể thực thi và lệnh đó sau đó có thể cho phép người dùng truy cập thêm. Xấu. –

1

Đây là những thư mục bình thường, chúng là "liên kết cứng" tới thư mục và thư mục hiện tại ở trên. Chúng có mặt trong tất cả các thư mục (ngay cả ở cấp cơ sở, trong đó .. chính xác giống như .).

Khi sử dụng ls, bạn có thể lọc ra ... với ls -A (chú ý vốn -A).

Khi áp dụng lệnh cho tất cả các tệp dot, nhưng không phải . hoặc .., tôi thường sử dụng .??* chỉ khớp với dấu chấm tệp có tên có ba ký tự trở lên.

touch .??* 

Lưu ý mô hình này cũng không bao gồm bất kỳ tập tin khác mà bắt đầu với dấu chấm và có chiều dài chỉ có hai ký tự (ví dụ .x) nhưng các tập tin không phổ biến.

Khi sử dụng trình nghe tệp có lập trình như readdir() Tôi phải loại trừ ... theo cách thủ công. Kể từ khi hai tập tin này có nghĩa vụ phải là người đầu tiên trong danh sách được trả về bởi readdir() bạn có thể làm điều này:

@files = readdir(DIR); 
for (1..2) { shift @files; } # get rid of . and .. 
# go on with your business 
+0

Hai dòng này nên được đưa vào một hàm. – Svante

+0

Làm sao bạn biết chúng không phải là * trong * một hàm? :-) –

+0

Rất kỳ quặc, trên Windows thư mục gốc (c: \, d: \, ...) không chứa bất kỳ liên kết nào trong hai liên kết. Trong khi bỏ qua .. người ta có thể làm cho một số ý nghĩa, bỏ qua. không làm. – Lemming

0

Họ được báo cáo bởi vì chúng được lưu trữ trong danh sách thư mục. Đó là cách các công đoàn luôn hoạt động.

0

Bởi vì trên các hệ điều hành giống Unix, các lệnh liệt kê danh sách bao gồm những điều đó và bạn sử dụng chúng để di chuyển lên và xuống trong hệ thống phân cấp hệ thống tệp.

Một cái gì đó như grep { not /^.{1,2}\z/ } readdir HANDLE sẽ phù hợp với bạn.

+1

Thực ra , chuỗi grep sẽ là /^\.{1,2}$/, vì khoảng thời gian cần được thoát. Tôi có lẽ sẽ viết này là /^\.\.?$/. –

-4

không có lý do chính đáng nào khi quét thư mục phải trả về các tên tệp này.

+0

Có mọi lý do quét thư mục phải trả về các tên tệp này. Làm thế nào để bạn viết getcwd()? –

+0

Đồng ý. Không có . và .., bạn không thể xử lý thư mục hiện tại hoặc thư mục gốc. –

+0

Tuy nhiên, tôi không hiểu lập luận này. Tôi đã cần phải biết thư mục hiện tại để có được "." nhập cảnh ở nơi đầu tiên ... – Lemming

3

Tôi có nghi ngờ rằng đây là những liên kết chỉ bình thường trong hệ thống tập tin và do đó không thể phân biệt từ file thực tế

Họ là. Trong khi bạn có thể cảm nhận hệ thống tệp là một hệ thống phân cấp của "thư mục" chứa "thư mục, thì nó thực sự là một cây được liên kết gấp đôi , với các thư mục là các nút và tệp tin là lá. Vì vậy, ... là các liên kết cần thiết để truy cập vào các nút của nút hiện tại và để duyệt qua cây và chúng giống như tất cả các liên kết khác.

Khi bạn gọi readdir, bạn sẽ nhận được tất cả các địa điểm bạn có thể trực tiếp chuyển đến từ nút hiện tại. Nếu bạn không muốn liệt kê các địa điểm mà bạn cảm nhận là "lên", bạn phải tự mình sắp xếp chúng. Bạn nên viết một hàm nhỏ cho điều đó, có lẽ được gọi là readdir_down. Tôi không biết trong đó thứ tự readdir liệt kê các thư mục, nhưng có lẽ bạn chỉ có thể vứt bỏ hai mục đầu tiên.

) đây là lần đầu tiên gần đúng, cũng có "liên kết cứng" có thể làm cho cây thực sự là mạng.

6

Ban đầu chúng là liên kết cứng và số lượng trường hợp đặc biệt trong mã hệ thống tệp. và .. tối thiểu. Tuy nhiên, điều đó không đúng đối với tất cả các hệ thống tập tin hiện đại.

Nhưng các quy ước đã được thiết lập sao cho ngay cả các hệ thống tệp nơi hai mục nhập thư mục này thực sự không tồn tại vẫn báo cáo sự tồn tại của chúng thông qua các API như readdir. Thay đổi điều này bây giờ sẽ phá vỡ rất nhiều mã.

Các vấn đề liên quan