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/bar
i foo//bar
zaró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 $PATH
zmienną ... Cholera, nawet staram się znaleźć odpowiednie tagi dla tego pytania!)
~
) 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.Odpowiedzi:
Istnieją trzy rodzaje ścieżek:
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ą./
,/foo/bar
lub///x
. Zaczynają się od 1, 3 lub więcej/
, nie są względne, są wyszukiwane zaczynając od/
katalogu głównego.//foo
być 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/$bar
lub inne. Jeśli chodzi o system,~foo
jest to ścieżka względna, taka jak_foo
lubfoo
.O czym należy pamiętać:
foo/
to nie to samo cofoo
. Jest to bliższefoo/.
niżfoo
(zwłaszcza jeślifoo
jest dowiązaniem symbolicznym) dla większości wywołań systemowych w większości systemów (foo//
jest tak samo jakfoo/
gdyby).a/b/../c
niekoniecznie jest taki sam jaka/c
(na przykład, jeślia/b
jest dowiązaniem symbolicznym). Najlepiej nie traktować..
specjalnie.a/././././b
to samo, jaka/b
gdyby.źródło
/
,.
i..
(?)//foo
obsługi jest Cygwin, gdzie jest on używany dla ścieżek UNC . Oznacza to, że//server/share/dir/file.txt
jest 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
.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///bar
afoo/////bar
także wskaż to samo miejsce cofoo/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).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.źródło
//
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”.