Reguły składni ścieżki

10

Piszę bibliotekę do manipulowania łańcuchami ścieżek uniksowych. W związku z tym muszę zrozumieć kilka niejasnych zakątków składni, o które większość ludzi by się nie martwiła.

Na przykład, jak najlepiej mogę powiedzieć, wydaje się, że foo/bari foo//barzarówno punkt do tego samego miejsca.

Ponadto, ~zazwyczaj oznacza katalogu domowym użytkownika, ale co zrobić, jeśli pojawi się on na środku ścieżki? Co się wtedy stanie?

Na te i kilkadziesiąt innych niejasnych pytań trzeba odpowiedzieć, jeśli mam napisać kod, który poprawnie obsługuje każdą możliwą sprawę. Czy ktoś wie o definitywnym odwołaniu, które wyjaśnia dokładne reguły składniowe dla tych rzeczy?

(Niestety, wyszukiwanie terminów takich jak „Składnia ścieżki uniksowej” po prostu pokazuje milion stron omawiających $PATHzmienną ... Cholera, nawet staram się znaleźć odpowiednie tagi dla tego pytania!)

MathematicalOrchid
źródło
ok ~ tylda i rozszerzenie nazwy pliku są podstawowymi funkcjami zdefiniowanymi przez POSIX w każdym środowisku uniksowym. Kilka wskazówek: nazwa pliku może być inna niż \ 0 lub /. ////// i / to to samo. $ PWD jest obsługiwany w jądrze i może być odczytany dla dowolnego procesu (Linux) w / proc. /./ może wystąpić tylko w katalogu głównym ścieżki. W $ PATH ::::: i: są tym samym. / dev / null / dev / tty i / tmp są ścieżkami gwarantowanymi przez POSIX dla każdego zgodnego systemu.
mikeserv
1
Większość twojego pytania (ale nie część ~) jest opisana w Jak Linux obsługuje wiele separatorów ścieżek (plik / home //// nazwa użytkownika ///) . Najbliżej normy jest odniesienie do specyfikacji POSIX lub Single Unix - niełatwy odczyt.
Gilles „SO- przestań być zły”

Odpowiedzi:

13

Istnieją trzy rodzaje ścieżek:

  • Względne ścieżki jak foo, foo/bar, ../a, .. Nie zaczynają się od /i są względne w stosunku do bieżącego katalogu procesu wykonującego wywołanie systemowe z tą ścieżką.
  • Ścieżki absolutne jak /, /foo/barlub ///x. Zaczynają się od 1, 3 lub więcej /, nie są względne, są wyszukiwane zaczynając od /katalogu głównego.
  • POSIX pozwala //foobyć traktowanym specjalnie, ale nie określa jak. Niektóre systemy używają tego w szczególnych przypadkach, takich jak pliki sieciowe . To muszą być dokładnie 2 ukośniki.

Poza początkiem sekwencje ukośników działają jak jeden.

~jest wyjątkowy tylko dla powłoki , jest rozszerzany przez powłokę, wcale nie jest wyjątkowy dla systemu. To, jak jest rozwinięty, zależy od powłoki. Powłoki wykonują inne formy rozszerzeń, takie jak globbing ( *.txt) lub rozwijanie zmiennych /$foo/$barlub inne. Jeśli chodzi o system, ~foojest to ścieżka względna, taka jak _foolub foo.

O czym należy pamiętać:

  • foo/to nie to samo co foo. Jest to bliższe foo/.niż foo(zwłaszcza jeśli foojest dowiązaniem symbolicznym) dla większości wywołań systemowych w większości systemów ( foo//jest tak samo jak foo/gdyby).
  • a/b/../cniekoniecznie jest taki sam jak a/c(na przykład, jeśli a/bjest dowiązaniem symbolicznym). Najlepiej nie traktować ..specjalnie.
  • generalnie bezpiecznie jest traktować a/././././bto samo, jak a/bgdyby.
Stéphane Chazelas
źródło
Tak w skrócie, jeśli nie dbam o muszli manipulacji ścieżki (co jest rozległe i skomplikowane), tylko trzeba się przejmować /, .i ..(?)
MathematicalOrchid
Przykładem //fooobsługi jest Cygwin, gdzie jest on używany dla ścieżek UNC . Oznacza to, że //server/share/dir/file.txtjest to legalna ścieżka domyślnie wskazująca system poza systemem. Cygwin wraca do patrzenia na system lokalny, jeśli nie może go znaleźć server.
Warren Young,
3

Na przykład, najlepiej jak potrafię powiedzieć, wydaje się, że oba foo / bar i foo // bar wskazują na to samo miejsce.

Tak. Jest to powszechne, ponieważ oprogramowanie czasami konkatenuje ścieżkę, zakładając, że pierwsza część nie została zakończona ukośnikiem do przodu, więc jeden jest wrzucany, aby się upewnić (co oznacza, że ​​może być dwóch lub więcej). foo///bara foo/////bartakże wskaż to samo miejsce co foo/bar. Fajną funkcją dla biblioteki manipulacji ścieżkami byłaby taka, która redukuje dowolną liczbę kolejnych ukośników do jednego (z wyjątkiem początku ścieżki, gdzie można jej użyć w sposób URL-owy lub, jak wskazuje Stephane, dla dowolnego nieokreślony cel specjalny).

Ponadto ~ zwykle oznacza katalog domowy użytkownika

Ta transformacja odbywa się poprzez rozszerzenie powłoki i tyldę , która działa tylko wtedy, gdy jest to pierwsza postać na ścieżce. To, czy musisz sobie z tym poradzić, zależy od kontekstu. Jeśli biblioteki mają być używane z normalnymi programami, które odbierają np. Argumenty wiersza poleceń zawierające ścieżkę, interpretacja tyldy jest już wykonywana, gdy widzą ścieżkę. Jedyną sytuacją, w której widzę problem, jest przetwarzanie ścieżek bezpośrednio z pliku tekstowego.

Poza tym ~jest to znak prawny na ścieżce * nix i nie należy go zmieniać na nic innego. W związku z tym jedynymi znakami, które nie są dozwolone w nazwie pliku unix, są /(ponieważ jest to separator ścieżki) i „null” (inaczej bajt zerowy), ponieważ ogólnie są one nielegalne w tekście.

Złotowłosa
źródło
+1 za wyjaśnienie rozszerzenia tylda; Nie miałem pojęcia, że ​​możesz odnieść się do innych użytkowników!
MathematicalOrchid
2
Jak mówi Stephane, nie można ślepo zwinąć wszystkich powtarzających się ukośników. Wiele ukośników na początku ścieżki należy traktować ostrożnie.
Warren Young,
@WarrenYoung Edytowane, aby to wyjaśnić. PS. Naprzód??! O_O
złotowłosa
Lepiej, choć nie powiedziałbym, że ma to coś wspólnego z adresami URL. UNC sięga późnych lat 80. XX wieku, a adresy URL pojawiły się dopiero po latach.
Warren Young,
@WarrenYoung Wystarczająco uczciwe, choć wydaje się, że UNC są specyficzne dla platform MS , więc //technicznie też nie jest to takie. Zarówno URLS, jak i nowsza, zgodnie z SC, swobodnie niejednoznaczna specyfikacja POSIX, // mogły zostać wyprowadzone z takich, w którym to przypadku „URL-ish” wydaje się trafną etykietą dla konwencji (nawet jeśli UNC są starsze, a nawet jeśli pozór jest niezamierzone). Nigdy nie powiedziałbym, że „są to adresy URL ”, tylko to //lub \\ służy celowi „URL-ish”.
złotowłosa