Czy jest jakaś różnica między ścieżkami „file” i „./file”?

12

Jak mówi tytuł, czy jest jakaś różnica w systemach plików * NIX? np. ls fileils ./file

Siergiej Alaev
źródło
1
Możesz zapytać unix.stackexchange.com - dotychczasowe odpowiedzi zawierają dobre informacje, ale żadne z nich tak naprawdę nie wydaje się odpowiedzią.
Rob Starling

Odpowiedzi:

14

Nie jestem szalony na wyjaśnienie SmallLoanOf1M. Jest to technicznie poprawne, ale odpowiada w sposób niezgodny z przykładem użycia w pytaniu.

Oto przykład ważnej różnicy między tymi dwoma pytaniami: „plik” i „./plik”

Co jeśli nazwa pliku zawiera znak analizowany przez powłokę? Zwłaszcza w odniesieniu do znaków interpretowanych przez polecenie, które się uruchamia.

W szczególności znak „myślnik”: „-”. Ale inne postacie mają znaczenie dla powłoki.

Przykład. Mój plik otrzymał nazwę „-dingle”

Spróbuj wyświetlić plik:

ls -dingle
# ls -dingle
ls: invalid option -- 'e'

Co gorsza, co jeśli plik miałby nazwę „ -rf rmbomb *”? Teraz spróbuj go usunąć

rm "-rf rmbomb *"

Nawet nie spróbuję podać tego przykładu, ale mam nadzieję, że wpadłeś na ten pomysł.

Jak wyświetlić plik z myślnikiem? Użyj ./z przodu.

# ls ./-dingle
./-dingle

To samo dotyczy rm

JDS
źródło
To prawidłowy sposób przetwarzania niektórych plików o nieparzystych nazwach, a moja odpowiedź nie uwzględniała takich plików. Zamiast tego można również użyć literału we wszystkich powyższych przykładach, w postaci odwrotnego ukośnika poprzedzającego znaki nieparzyste, w tym spacje określone powyżej. Przykładem może być: ls \-dinglelub ls \-rf\ rmbomb\ \*. Może to być dobry sposób na upewnienie się, że dowolny zestaw poleceń jest co najmniej spójny, ponieważ określenie ./przed nazwą nie będzie poprzedzać znaków po znaku ./.
Spooler
2
Zdarza się, że ponieważ znaki ucieczki są usuwane przez powłokę, a nie polecenie, a parametry są analizowane przez polecenie, ucieczka lub cytowanie - nie robi nic użytecznego.
Dewi Morgan
2
Sprawiasz, że brzmi to tak rm "-rf rmbomb *", jakby zrobił coś złego, zamiast po prostu rmdrukować błąd. Jest to niebezpieczne tylko wtedy, gdy zapomnisz zacytować nazwę pliku, co powoduje dzielenie słów. (szczególnie w skrypcie powłoki, w którym uruchamiasz się rm $filezamiast rm "$file". Ale w takim przypadku *nie będzie się rozwijało, ponieważ rozszerzenie globalne nie dzieje się na zawartości zmiennej rozwijanej. Jeśli chcesz, potrzebujesz eval.) W każdym razie, jeśli twoje skrypty dzielą nazwy plików przed przekazaniem do rm, utworzę plik o nazwie space -rf .lub coś takiego, więc rm ./$ito nie pomaga.
Peter Cordes
1
BTW, rzeczywistym komunikatem o błędzie jest rm: invalid option -- ' 'od momentu, gdy próbuje on interpretować spację później -rfjako przełącznik jednoznakowy, ponieważ jest częścią tego samego argumentu. (I tak, włączyłem to do pustego katalogu na wypadek, gdy coś przeoczyłem i było to naprawdę niebezpieczne: P)
Peter Cordes
2
@PeterCordes: dzielenie słów i globowanie DOES występują w wyniku niecytowanej interpretacji zmiennych i podstawiania poleceń, chyba że są odpowiednio pomijane IFS=''i -f. Rzadszym przykładem jest to, że awktraktuje operand (inny niż pierwszy operand, którym jest skrypt) mający formę foo=barjako zadanie do wykonania, ale ./foo=barjako plik do odczytu.
dave_thompson_085
7

Tak.

Wydając filew wierszu poleceń, BASH przeszuka zmienną środowiskową $ PATH w poszukiwaniu pliku o tej nazwie. O ile plik nie znajduje się w katalogu w zmiennej $ PATH, nie zostanie znaleziony.

.oznacza bieżący katalog. ./oznacza w bieżącym katalogu, w kategoriach względnych. Jest to odpowiednik powiedzenia czegoś takiego jak /home/sheogorath/shivering/isles.imgpodczas wywoływania ./isles.imgpodczas pracy w /home/sheogorath/shivering/katalogu.

Jako taki jest powszechnie używany do wykonywania plików w katalogu roboczym „na miejscu”.

EDYCJA: W twoim przykładzie lsjest wywoływany przez powłokę i znaleziony przy użyciu zmiennej path. Jego argument zostanie przetworzony w twoim katalogu roboczym, cokolwiek to może być. Ponieważ jest to ustawienie domyślne ls, nie zobaczysz żadnej różnicy między określaniem filea jawnym określaniem, ./fileponieważ oba wskazują na bieżący katalog.

Nie wszystkie polecenia akceptują ścieżki do plików w katalogu roboczym, a niektóre oczekują, że ustawisz pliki w katalogu, który oni sami wstępnie określają poprzez konfigurację. Wśród poleceń, które akceptują pliki jako argumenty, polecenia te są mniej powszechne

Bufor
źródło
1
To jest bash, ale zastanawiałem się nad rozwiązaniem ścieżki w ogóle
Sergey Alaev
1
W ten sposób działa jakakolwiek skorupa, o której słyszałem. BASH jest jedynie najczęściej stosowanym.
Spooler
4
$ PATH dotyczy tylko poleceń i nie ma nic wspólnego z argumentami nazw plików, które następują po poleceniach, takich jak lswspomniane w pierwotnym pytaniu. To jest bardziej różnica między odnowieniem ścieżki względnej (w stosunku do bieżącego katalogu roboczego) Tj. ../../dir/filenameA ścieżką bezwzględną /path/to/dir/filename
HBruijn
1
+1 dla Sheogoratha ... i poprawna odpowiedź.
Corey Ogburn,
1
Jeśli są argumentami polecenia, które domyślnie próbuje znaleźć pliki w katalogu roboczym, będą takie same. Tak więc, lsponieważ zawsze będą one tą samą ścieżką, jedną określoną bardziej wyraźnie niż drugą. Nie wszystkie polecenia zachowują się w ten sposób podczas przetwarzania argumentów, ale większość tak.
Spooler