Spodziewałem się, że nie otrzymam żadnych wyników.
Gdyby nullglobbyły domyślne, wiele poleceń zachowywałoby się dość nieoczekiwanie, ponieważ (być może niestety) często polecenia traktują sprawę zerowych argumentów nazw plików w jakościowo odmienny sposób niż przypadek jednego lub więcej argumentów nazw plików.
Załóżmy, że masz włączoną funkcję nullglob( shopt -s nullglob) i jesteś w katalogu, w którym nie ma pasujących plików *.txt. Wtedy *.txtrzeczywiście rozwinie się do zera - nie pustego pola, ale żadnych pól - zgodnie z oczekiwaniami. Ale to przyniosłoby następujące wyniki:
ls *.txtwyświetlałby listę wszystkich plików w bieżącym katalogu (oprócz plików ukrytych), ponieważ dzieje się lstak, gdy nie przekaże się żadnych argumentów nazw plików.
cat *.txtczytałby ze standardowego wejścia , ponieważ gdy catnie ma argumentów nazwy pliku, to tak jakbyś uruchomił cat -. Jeśli działa interaktywnie, siedzi i czeka na dane wejściowe. Wiele poleceń zachowuje się w ten sposób.
cp *.txt dest/nie powiedzie się z powodu błędu cp: missing destination file operand after 'dest/'. To nie jest katastrofa, ale jest myląca i zupełnie inna niż cichy sukces, który prawdopodobnie jest pożądany.
file *.txt, i różne inne programy bez specjalnego zachowania w przypadku argumentów zerowej nazwy pliku, nadal nie powiodłyby się z komunikatem o błędzie lub użytkowaniu, gdy żaden nie zostanie przekazany.
- Nawet przypadki, które intuicyjnie czują, że powinny działać, często by tego nie zrobiły.
printf 'Got file: "%s"\n' *.txtwydrukuje Got file: ""zamiast niczego.
- Przypadkowe uszkodzenie zacytować wystąpień
*, ?i [które nie są przeznaczone do rozszerzony przez powłokę będzie częściej produkują oczywiście błędne wyniki, ale w sposób, który może być trudny do rozszyfrowania. Na przykład, jeśli żadna nazwa pliku w bieżącym katalogu nie zaczyna się od gedit, wtedy apt list gedit*(gdzie apt list 'gedit*'zamierzano) stałby się sprawiedliwy apt listi wyświetlałby listę wszystkich dostępnych pakietów.
Dobrze więc, że nie dostajesz tego zachowania bez żądania go. Prawdopodobnie najczęstszą praktyczną sytuacją, która jest w rzeczywistości uproszczona, nullglobjest for f in *.txt. Zobacz także to pytanie (z którym łączy się odpowiedź Siergieja Kolodyazhnyya ).
Trudniejsze pytanie brzmi: dlaczego - failglobw przypadku błędu rozszerzenia brak globu, który nie pasuje do żadnego pliku - nie jest domyślny w bash. Uważam, że odpowiedź Siergieja Kolodyazhnyya zawiera przyczynę tego, nawet bez bezpośredniego odesłania . Zatrzymywanie nierozwijających się globów bez powodowania błędu ekspansji jest (być może niestety) znormalizowanym zachowaniem, a także zachowaniem tradycyjnym, a zatem oczekiwanym. Chociaż bash nie próbuje być w pełni zgodny z POSIX, chyba że zostanie wywołany z nazwą shlub nie prześle --posixopcji, wiele z jego opcji projektowych, nawet gdy nie jest w trybie POSIX, następuje bezpośrednio po POSIX. Musieli wybrać pewne zachowanie i są wady związane z nieprzestrzeganiem oczekiwań użytkowników.
Myślę, że jest to najmniej wpływowy historycznie aspekt tej sprawy, więc zostawiłem to na koniec ... ale warto wspomnieć, że w zachowaniu jest coś dziwnie koncepcyjnego nullglob.
nullglobna pierwszy rzut oka wydaje się elegancki, ponieważ pod względem składniowym traktuje przypadek zero pasujących plików nie inaczej niż przypadek jednego, dwóch lub dowolnej innej liczby. Uruchamiane przez nas polecenia, dla których globusy zamieniają się w argumenty, nie traktują ich tak samo, jak opisano powyżej. Ale syntaktycznie wydaje się to co najmniej słuszne, co myślę, że jest motywacją do twojego pytania.
A jednak istnieje inna, bardziej subtelna niespójność, nullglobktóra nie rozwiązuje problemu - a która nasila. Przypadek zerowania znaków globowania („symboli wieloznacznych”) jest traktowany zupełnie inaczej niż w przypadku jednej, dwóch lub dowolnej innej liczby. Na przykład, shopt -s nullglobjeśli ab?d?fnie pasuje do żadnego pliku, jest usuwany; jeśli ab?dnie pasuje do żadnego pliku, jest usuwany; ale jeśli abnie pasuje do żadnego pliku (tzn. jeśli nie ma pliku o dokładnie takiej nazwie ab), nadal nie jest usuwany. Oczywiście byłoby katastrofą, gdyby został usunięty, ponieważ może nie być przeznaczony do odwoływania się do istniejącego pliku w bieżącym katalogu; może nawet nie odnosić się do pliku. Ale to wciąż eliminuje wszelką nadzieję na całkowitą spójność.
Trzy zachowania, które zapewnia bash - domyślne traktowanie globów, które nie pasują do żadnych plików, tak jakby nie były globami, i przekazywanie ich jako nierozwinięte, zachowanie, którego się spodziewałeś po ich traktowaniu (jeśli wybaczysz ten dziwny zwrot frazy) jako oznaczające wszystkie zero plików, które pasują do siebie ( nullglob), oraz bezpieczne zachowanie polegające na uznaniu ich za błędy ( failglob) - wszystkie reprezentują różne podejścia do dwuznaczności związanej z powłoką, która nie jest w stanie stwierdzić, czy jakieś konkretne słowo ma być Nazwa pliku. Powłoka wykonuje ekspansje bez wiedzy o tym, jak poszczególne polecenia, które wywołujesz, będą traktować ich argumenty.
Jest to jeden z wielu przypadków rozdzielenia obaw . W systemach, których projekt jest zgodny z filozofią Uniksa, każda część ma na celu zrobienie jednej rzeczy i wykonanie jej dobrze . Powłoka przetwarza tekst na polecenia i argumenty i wywołuje te polecenia, z których większość jest zewnętrzna względem samej powłoki. Jest to zwykle o wiele ładniejsze i bardziej wszechstronne niż systemy, w których polecenia zewnętrzne są same odpowiedzialne za wykonywanie tych transformacji (jak w przypadku tradycyjnych procesorów poleceń w DOS i Windows). Ale ma to czasem swoje wady.
shopt -s nullglobda puste ciągi dla niedopasowanych wzorów ishopt -u nullglob(ustawienie standardowe) da sam wzór.