Czy dobrą praktyką jest wymaganie ukośnika końcowego w nazwach katalogów?

9

Chcę poprosić użytkownika mojego skryptu bash o podanie ścieżki katalogu jako argumentu. Które z poniższych jest dobrą praktyką programowania?

  • Wymagaj, aby użytkownik wprowadził końcowe / (ukośnik)
  • Wymagaj, aby użytkownik nie wprowadzał końcowego / (ukośnika)
Rohit Agarwal
źródło
3
Zauważ, że rsynczachowuje się inaczej w bardzo ważny sposób w zależności od obecności końca /, więc w niektórych przypadkach chciałbyś znormalizować dla spójności, a w innych chciałbyś przejść czysto, aby wdrożyć to, co powiedział użytkownik (jeśli wiedziałem, że rozmawiają rsync).
sh1
Kolejnym, który mnie ostatnio zaskoczył, jest to, że ls -l dirzachowuje się inaczej niż ls -l dir/jeśli dirjest dowiązaniem symbolicznym do katalogu.
Flimm,

Odpowiedzi:

27

Najlepszą praktyką jest nie zakładanie żadnego z nich.

Jeśli masz dostęp do narzędzi / klas narzędzia do budowania ścieżek, skorzystaj z nich, jeśli nie, napisz kod, aby zaakceptować dowolny format i odpowiednio postępować.

Nic nie jest bardziej denerwujące dla użytkownika niż konieczność pamiętania, czy dodać ukośnik końcowy, czy nie.

ChrisF
źródło
6
Następstwem: Zawsze analizy: Ścieżki z odpowiednich narzędzi wiersza polecenia - dirname, basenamei readlink. Bardzo częstym problemem jest ${path##*/}zastępowanie basename, ale jeśli ścieżka kończy się ukośnikiem, który zwraca pusty ciąg zamiast ostatniego elementu ścieżki.
l0b0
1
+1 za korzystanie z klas użyteczności. Nie mogę powiedzieć, ile razy widziałem, jak programiści wymyślają na nowo koło, jeśli chodzi o składanie ścieżek, kiedy większość frameworków może to teraz łatwo zrobić.
RationalGeek,
1
Jestem również bardzo zirytowany, gdy jakaś aplikacja wymaga ode mnie zrobienia tego w określony sposób. A czasami użytkownik nie może kontrolować, jak napisać tę ścieżkę: czasami pisze, więc tak, decyduje się na pisanie z ukośnikiem lub bez, ale w przypadkach, gdy użytkownik autouzupełnia za pomocą TAB, wiele powłok umieszcza ukośnik, więc musisz go usunąć? Jeszcze bardziej irytujące jest to, że aplikacja zachowuje się inaczej, jeśli umieścisz ukośnik w katalogu przekazywanym jako argument ( rsyncpatrzę na ciebie)
Carlos Campderrós,
Ostatnio potrzebowałem zweryfikować ukośnik od danych wejściowych użytkownika do użycia z rsync (ponieważ jest wrażliwy na te rzeczy). Jak zauważył @ChrisF, najlepszą praktyką jest zakładanie żadnego z nich. Wymyśliłem następujące jako wdzięczny sposób zakładania, że ​​nie: ${STR}$(printf \\$(printf '%03o' $(($(printf '%d' "'${STR:(-1)}")==47?0:47))))udokumentowałem to również dla jasności: dodaj lub usuń końcowy ukośnik w bash
John Mark Mitchell,
10

Ponieważ bash ignoruje wiele ukośników, możesz bezpiecznie założyć, że użytkownik nie wprowadził ukośnika na ścieżce i sam go dodać.

cat /etc/hosts

jest taki sam jak

cat /////etc//////////hosts

Twój skrypt może wyglądać następująco:

echo -n "enter path: "
read path
if [ -f $path/myfile ]
then
  echo "found myfile!"
else
  echo "nope"
fi

i nie musisz się martwić, czy użytkownik wejdzie na trailing / na ścieżkę.

użytkownik 281377
źródło
5
Nit: To nie jest bashzachowanie, jądro to robi.
Blrfl
7

Zmarły Jon Postel miał kilka świetnych rad w sekcji 3.2 RFC 760, które mają tutaj zastosowanie:

Zasadniczo implementacja powinna być zachowawcza w zachowaniu wysyłającym i liberalna w zachowaniu przyjmującym. Oznacza to, że należy ostrożnie wysyłać dobrze uformowane datagramy, ale powinien akceptować każdy datagram, który może zinterpretować (np. Nie sprzeciwić się błędom technicznym, których znaczenie jest nadal jasne).

Blrfl
źródło
3

Pod względem koncepcyjnym ukośnik nie jest częścią nazwy. Ukośnik jest tylko separatorem między nazwami. Mój katalog domowy to / home / stefan, a nie / home / stefan /.

Jeśli nie spodziewasz się końcowego ukośnika, nie zawiedziesz, jeśli taki istnieje, jak już wspomniano amunicji. Ale możesz łatwo skleić nazwy i zmienne, ponieważ nie musisz cytować ukośnika:

a="/home"
b="stefan"

dir=$a/$b
nieznany użytkownik
źródło
0

Wymaganie, aby katalog nie zawierał ukośnika końcowego, byłoby bardzo denerwujące dla interaktywnego użycia na konsoli: automatyczne uzupełnianie za pomocą TAB automatycznie dodaje ukośnik końcowy dla katalogów.

Więc na pewno musisz zezwolić, aby katalogi były oznaczone końcowym ukośnikiem.

oberlies
źródło