W powłokach POSIX .
jest specjalnym wbudowanym narzędziem, więc jego awaria powoduje zamknięcie powłoki (w niektórych takich powłokach bash
robi się to tylko w trybie POSIX).
To, co kwalifikuje się jako błąd, zależy od powłoki. Nie wszystkie z nich wychodzą po błędzie składni podczas analizowania pliku, ale większość kończy działanie, gdy nie można znaleźć lub otworzyć pliku źródłowego. Nie znam żadnego, który by się zakończył, gdyby ostatnie polecenie w pliku źródłowym zwróciło z niezerowym statusem wyjścia (chyba że errexit
opcja jest oczywiście włączona).
Tutaj robiąc:
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Jest to przypadek, w którym chcesz pobrać plik, jeśli on tam jest, i nie rób tego, jeśli go nie ma (lub jest pusty tutaj -s
).
Oznacza to, że nie należy go uważać za błąd (błąd krytyczny w powłokach POSIX), jeśli pliku nie ma, plik ten jest uważany za plik opcjonalny.
Nadal byłby (krytyczny) błąd, gdyby plik nie był czytelny lub był katalogiem lub (w niektórych powłokach), jeśli wystąpił błąd składniowy podczas analizowania go, co byłoby prawdziwymi warunkami błędu, które należy zgłosić.
Niektórzy twierdzą, że istnieje warunek wyścigu. Ale jedyne co to oznacza, to że powłoka wyjdzie z błędem, jeśli plik zostanie usunięty pomiędzy [
i .
, ale argumentuję, że uzasadnione jest uznanie za błąd, że ten ustalony plik ścieżki nagle zniknie, gdy skrypt jest bieganie.
Z drugiej strony,
command . "$NVM_DIR/nvm.sh" 2> /dev/null
gdzie command
¹ usuwa specjalny atrybut .
polecenia (aby nie opuścił powłoki po błędzie) nie działałby, ponieważ:
- ukrywałoby
.
to błędy, ale także błędy poleceń uruchamianych w pliku źródłowym
- ukryłoby to również rzeczywiste warunki błędu, takie jak plik mający nieprawidłowe uprawnienia.
Inne typowe składnie (zobacz na przykład grep -r /etc/default /etc/init*
w systemach Debian skrypty inicjujące, na które nie zostały systemd
jeszcze przekonwertowane (gdzie EnvironmentFile=-/etc/default/service
zamiast tego określa się opcjonalny plik środowiska)):
[ -e "$file" ] && . "$file"
Sprawdź plik, który tam jest, wciąż go źródłuj, jeśli jest pusty. Nadal błąd krytyczny, jeśli nie można go otworzyć (nawet jeśli już tam jest lub był). Możesz zobaczyć więcej wariantów, takich jak [ -f "$file" ]
(istnieje i jest zwykłym plikiem), [ -r "$file" ]
(jest czytelny) lub ich kombinacje.
[ ! -e "$file" ] || . "$file"
Nieco lepsza wersja. Wyjaśnia, że nieistniejący plik jest przypadkiem OK. Oznacza to również, że $?
będzie odzwierciedlał status wyjścia ostatniego polecenia uruchomionego w $file
(w poprzednim przypadku, jeśli tak 1
, nie wiesz, czy to dlatego, $file
że nie istniało, czy to polecenie nie powiodło się).
command . "$file"
Spodziewaj się, że plik tam będzie, ale nie zamykaj go, jeśli nie można go zinterpretować.
[ ! -e "$file" ] || command . "$file"
Kombinacja powyższych: jest OK, jeśli pliku nie ma, a dla powłok POSIX nieudane otwarcie (lub parsowanie) pliku jest zgłaszane, ale nie jest krytyczne (co może być bardziej pożądane ~/.profile
).
¹ Uwaga: zsh
Jednak nie można tego używać command
, chyba że w sh
emulacji; zwróć uwagę, że w powłoce Korna source
jest tak naprawdę pseudonimem command .
, niespecjalnym wariantem.