Chém dấu gạch chéo trên các liên kết tượng trưng đến thư mục


8

Tôi đang cố gắng mô phỏng quá trình phân giải đường dẫn (xem path_resolution của trang man) trong các hệ thống giống như unix.

HĐH của tôi là Linux với GNU coreutils 8.7.

Để làm rõ ý nghĩa của việc thêm dấu '/' trong độ phân giải, tôi đã làm theo những điều sau đây:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link

Mọi thứ đều ổn, bởi vì this_is_link là một liên kết tượng trưng và tôi chỉ xóa nó đi. Nhưng trong khi thử:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/

Nó lặp lại rm: cannot remove 'this_is_link/': Is a directory

Chà, dấu vết '/' gây ra sau symlink, tôi nghĩ vậy. Vì vậy, tôi đã thử một lệnh khác:rmdir this_is_link/

Và một kết quả hài hước xuất hiện: rmdir: failed to remove 'this_is_link/': Not a directory

Không phải những gì tôi mong đợi. Vì vậy, tôi đã yêu cầu bạn tôi xác nhận nếu kết quả tương tự có thể thu được trên hệ thống của anh ta. Anh ta có một phiên bản lõi thấp hơn tôi. Và kết quả thật đáng kinh ngạc, không có vấn đề rmhay rmdir 'this_is_link/', cùng một lỗi Not a directoryxảy ra .

Và một người bạn khác vừa dùng thử trên Mac OS của anh ta, kết quả là: rm=> 'Là một thư mục', rmdir=> thư mục bị xóa thành công, liên kết vẫn còn .

Có bất kỳ thông số kỹ thuật về hành vi chính xác của độ phân giải đường dẫn?


Câu trả lời:


7

Đặc tả kỹ thuật POSIX / Single Unix chỉ định rằng một tên đường dẫn có dấu gạch chéo phải tham chiếu đến một thư mục (xem định nghĩa cơ sở độ phân giải tên đường dẫn §4.11 ). foo/trong thực tế được định nghĩa là tương đương với foo/.(cho mục đích phân giải đường dẫn, không phải khi thao tác tên tệp; basenamedirnamebỏ qua dấu gạch chéo). Hầu hết các triển khai đều tôn trọng điều này, nhưng có một vài trường hợp ngoại lệ.

Điều này giải thích hành vi của rm this_is_link/: nó tương đương với rm this_is_link/., trong đó đối số rõ ràng là một thư mục.

rmdir this_is_link/tương tự nên tham khảo thư mục. Rằng nó không có trên máy của bạn là một lỗi trong lõi GNU. OSX đang hành xử chính xác ở đây.


Đây chính xác là những gì tôi cần, cảm ơn anh chàng!
ymfoi

-1

Tôi lấy:

  • '' rm link / '' thất bại vì rm nhìn vào char cuối cùng, thấy đó là một dấu gạch chéo, đưa ra chẩn đoán (không thực sự chính xác) mà bạn đã thấy;
  • '' rmdir link / '' fail alright: link không phải là một thư mục, nó là một liên kết tượng trưng
  • '' rm link '' sẽ thành công chính xác

Ngẫu nhiên, độ phân giải đường dẫn có rất ít liên quan đến vấn đề này, nó chỉ xuất hiện là '' rm '' cắt một góc chứ không phải (gọi chính xác) gọi "stat" trên một đối số (đó là những gì rmdir đang làm).

Chúc mừng.


1
Trên thực tế, điều ngược lại có vẻ đúng: thực sự rmgọi stat (tốt, newfstatat, thực tế, với AT_SYMLINK_NOFOLLOWtùy chọn) và từ chối tiếp tục, trong khi rmdir thực sự gọi rmdir (2), nhưng được ENOTDIR.
Ansgar Esztermann

@AnsgarEsztermann AT_SYMLINK_NOFOLLOWsẽ ngăn không cho nó theo symlink, vì vậy rm nên xóa chính liên kết đó thay vì in "Không phải là một thư mục" không phù hợp với hoàn cảnh.
ymfoi

Từ một kiểm tra ngắn với stat (1), dấu gạch chéo sẽ ghi đè tùy chọn. Đầu ra của statstat -Lchỉ khác nhau nếu đối số được đưa ra mà không có dấu gạch chéo.
Ansgar Esztermann

@AnsgarEsztermann Ồ, tôi hiểu rồi ... Thx. Làm thế nào về các hiệu ứng khác nhau trên evironment khác nhau? Có ý kiến ​​gì không?
ymfoi

1
Điều ngược lại: trên máy của ymfoi, rmđang hoạt động chính xác và rmdirkhông. Việc theo dõi /sẽ buộc họ coi đối số của họ là một thư mục, theo tiêu chuẩn POSIX. Xem câu trả lời của tôi để tham khảo .
Gilles 'SO- ngừng trở nên xấu xa'
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.