Quy tắc cú pháp đường dẫn


10

Tôi đang viết một thư viện để thao tác các chuỗi đường dẫn Unix. Trong trường hợp đó, tôi cần hiểu một vài góc tối nghĩa của cú pháp mà hầu hết mọi người sẽ không lo lắng.

Ví dụ, tốt nhất như tôi có thể nói, có vẻ như foo/barfoo//barcả hai đều chỉ đến cùng một nơi.

Ngoài ra, ~thường là viết tắt của thư mục chính của người dùng, nhưng nếu nó xuất hiện ở giữa một đường dẫn thì sao? Điều gì xảy ra sau đó?

Những câu hỏi này và vài chục câu hỏi khó hiểu khác cần trả lời nếu tôi sẽ viết mã xử lý chính xác mọi trường hợp có thể. Có ai biết một tài liệu tham khảo chính xác giải thích các quy tắc cú pháp chính xác cho công cụ này không?

(Thật không may, tìm kiếm các thuật ngữ như "cú pháp đường dẫn Unix" chỉ xuất hiện một triệu trang thảo luận về $PATHbiến ... Heck, tôi thậm chí đang vật lộn để tìm các thẻ phù hợp cho câu hỏi này!)


ok ~ mở rộng dấu ngã và -filename là các tính năng được xác định POSIX cơ bản của bất kỳ môi trường Unix nào. Một số mẹo: tên tệp có thể là bất cứ thứ gì ngoại trừ \ 0 hoặc /. ////// và / là cùng một thứ. $ PWD được xử lý trong kernel và có thể được đọc cho bất kỳ quy trình (Linux) nào trong / Proc. /./ chỉ có thể xảy ra ở thư mục gốc. Trong $ PATH ::::: và: là những điều tương tự. / dev / null / dev / tty và / tmp là các đường dẫn được bảo đảm POSIX cho mọi hệ thống tuân thủ.
mikeerv

1
Hầu hết câu hỏi của bạn (nhưng không phải là phần về ~) được đề cập trong Cách linux xử lý nhiều dấu tách đường dẫn (/ home //// tên người dùng /// tệp) . Thứ gần nhất với một tham chiếu quy phạm sẽ là đặc tả POSIX hoặc Unix đơn - không dễ đọc.
Gilles 'SO- ngừng trở nên xấu xa'

Câu trả lời:


13

Có ba loại đường dẫn:

  • đường dẫn tương đối thích foo, foo/bar, ../a, .. Chúng không bắt đầu bằng /và liên quan đến thư mục hiện tại của quá trình thực hiện cuộc gọi hệ thống với đường dẫn đó.
  • đường dẫn tuyệt đối như /, /foo/barhoặc ///x. Chúng bắt đầu bằng 1 hoặc 3 hoặc nhiều hơn /, chúng không tương đối, được tra cứu bắt đầu từ /thư mục gốc.
  • POSIX cho phép //foođược đối xử đặc biệt, nhưng không chỉ định cách thức. Một số hệ thống sử dụng cho các trường hợp đặc biệt như tệp mạng . Nó phải chính xác là 2 dấu gạch chéo.

Khác với lúc bắt đầu, chuỗi các dấu gạch chéo hoạt động như một.

~Nó chỉ đặc biệt đối với vỏ , nó được mở rộng bởi vỏ, nó không đặc biệt đối với hệ thống. Làm thế nào nó mở rộng là phụ thuộc vỏ. Shell thực hiện các hình thức mở rộng khác như Globing ( *.txt) hoặc mở rộng biến đổi hoặc các dạng /$foo/$barkhác. Theo như hệ thống có liên quan ~foochỉ là một đường dẫn tương đối như _foohay foo.

Những điều cần lưu ý:

  • foo/không giống như foo. Nó gần foo/.hơn foo(đặc biệt nếu foolà một liên kết tượng trưng) cho hầu hết các cuộc gọi hệ thống trên hầu hết các hệ thống ( foo//giống như foo/mặc dù).
  • a/b/../ckhông nhất thiết phải giống như a/c(ví dụ nếu a/blà một liên kết tượng trưng). Tốt nhất là không đối xử ..đặc biệt.
  • Nó thường an toàn để xem xét a/././././bgiống như a/bmặc dù.

Vì vậy, trong Tóm lại, nếu tôi không quan tâm đến vỏ con đường thao túng (đó là rộng lớn và phức tạp), tôi chỉ cần quan tâm đến /, ...(?)
MathematicalOrchid

Một ví dụ về //fooxử lý là ở Cygwin, nơi nó được sử dụng cho các đường dẫn UNC . Đó là, //server/share/dir/file.txtmột đường dẫn pháp lý chỉ ra ngoài hệ thống theo mặc định. Cygwin không quay lại nhìn vào hệ thống cục bộ nếu không thể tìm thấy server.
Warren Young

3

Ví dụ, tốt nhất như tôi có thể nói, có vẻ như foo / bar và foo // bar đều trỏ đến cùng một vị trí.

Đúng. Điều này là phổ biến vì đôi khi phần mềm ghép nối một đường dẫn giả sử phần đầu tiên không bị chấm dứt bằng dấu gạch chéo về phía trước, do đó, phần mềm được ném vào để đảm bảo (có nghĩa là cuối cùng có thể có hai hoặc nhiều hơn). foo///barfoo/////barcũng chỉ đến cùng một nơi với foo/bar. Một hàm đẹp cho thư viện thao tác đường dẫn sẽ là một hàm làm giảm bất kỳ số lượng dấu gạch chéo liên tiếp nào xuống một (ngoại trừ ở đầu đường dẫn, trong đó nó có thể được sử dụng theo cách URL, hoặc, như Stephane chỉ ra, cho bất kỳ mục đích đặc biệt không xác định).

Ngoài ra, ~ thường là viết tắt của thư mục nhà của người dùng

Sự biến đổi đó được thực hiện thông qua exapansion shell và tilde , chỉ hoạt động nếu nó là ký tự đầu tiên trong đường dẫn. Việc bạn có cần giải quyết vấn đề này hay không phụ thuộc vào ngữ cảnh. Nếu thư viện sẽ được sử dụng với các chương trình bình thường nhận, ví dụ: đối số dòng lệnh chứa đường dẫn, việc mở rộng dấu ngã đã được thực hiện khi chúng nhìn thấy đường dẫn. Tình huống duy nhất tôi có thể thấy nó là một mối quan tâm là nếu bạn đang xử lý các đường dẫn trực tiếp từ một tệp văn bản.

Ngoài ra, ~là một nhân vật hợp pháp trong đường dẫn * nix và không nên thay đổi thành bất kỳ điều gì khác. Theo điều này , các ký tự duy nhất không hợp pháp trong tên tệp unix là /(vì nó là dấu phân cách đường dẫn) và "null" (hay còn gọi là byte 0) vì chúng thường không hợp lệ trong văn bản.


+1 cho giải thích về việc mở rộng dấu ngã; Tôi không biết bạn có thể giới thiệu người dùng khác với nó!
Toán học,

2
Như Stephane nói, bạn không thể sụp đổ một cách mù quáng tất cả các dấu gạch chéo về phía trước. Nhiều dấu gạch chéo về phía trước khi bắt đầu đường dẫn phải được xử lý cẩn thận.
Warren Young

@WarrenYoung Đã chỉnh sửa để làm rõ điều này. Tái bút Ở đằng trước??! O_O
goldilocks

Tốt hơn, mặc dù tôi sẽ không nói điều này có liên quan đến URL. UNC quay trở lại vào cuối những năm 1980, trong khi các URL không xuất hiện cho đến nhiều năm sau đó.
Warren Young

@WarrenYoung Đủ công bằng, mặc dù có vẻ như UNC dành riêng cho nền tảng MS , //về mặt kỹ thuật cũng không phải vậy. Cả URLS và thông số POSIX mới hơn, theo SC-mơ hồ tự do cho // có thể đã được bắt nguồn từ đó, trong trường hợp đó, "URL-ish" dường như là một nhãn apt cho quy ước (ngay cả khi UNC cũ hơn và ngay cả khi bán kết là vô ý). Tôi sẽ không bao giờ nói rằng "chúng là URL", chỉ có điều đó //hoặc \\ phục vụ mục đích "URL-ish".
goldilocks
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.