Co chciałbyś zamiast tego zrobić? rm
W ogóle nie działa (1)? Czy uruchomić go z dosłownym *
argumentem, jak w innych powłokach podobnych do Bourne'a (2)? Uruchomić bez żadnych argumentów (3)?
files=(*(N)); (($#files)) && rm -- $files
. Albo (rm -- *) 2> /dev/null
ale również ukryć rzeczywiste błędy przez rm
co byłoby głupie. Możesz odrzucić zsh
błąd, ale przywróć stderr dla rm
polecenia za pomocą(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Potem jak w sh
który zsh
teraz emulowane dla tej linii pojedynczej poleceń, bez dopasowywania *
jest przekazywana jako-jest rm
i rm
skarży się, jako że *
plik nie istnieje. Mamy tłumić rm
„s stderr jak można zrobić w sh
celu powstrzymania, że komunikat o błędzie, ale znowu, że to głupie, jak to ukryć prawdziwych błędów, rm
w przeciwieństwie do błędu poniesionych przez pobycie sh
przechodząc dosłownym *
się rm
. rm -f '*'
nie narzekałby jednak na nieistniejący *
plik, więc możesz to zrobićemulate sh -c 'rm -f -- *'
rm -- *(N)
. rm
byłoby narzekać chociaż gdy nie przeszedł żadnego argumentu, choć znowu nie rm -f
: rm -f -- *(N)
.
Ogólnie rzecz biorąc, rm -f
to polecenie, którego chcesz użyć, jeśli chcesz, aby wszystkie pliki zniknęły i pojawia się błąd tylko wtedy, gdy plików nie można usunąć lub IOW nadal tam są po rm
powrocie. Zasadniczo chcesz również używać -f
skryptów, aby uniknąć monitowania użytkownika w niektórych sytuacjach.
Tutaj dzwonienie, rm
gdy glob nie pasuje, jest błędne. Zachowanie sh
1 jest nieprawidłowe. Jest to nieszkodliwe dla takiego wzoru *
, ale dla takiego jak *.[ch]
, przekazanie takiego *.[ch]
jak jest, gdy nie pasuje, może spowodować *.[ch]
pomyłkowe usunięcie pliku:
$ ls
*.[ch] foo.txt
$ zsh -c 'rm *.[ch]'
zsh:1: no matches found: *.[ch]
$ ls
*.[ch] foo.txt
$ sh -c 'rm *.[ch]'
$ ls
foo.txt
Niepowodzeniem z błędem jest najbardziej sensowne rzeczy do zrobienia i to, co zsh
(i fish
, csh
, tcsh
, bash -o failglob
i oryginalny Unix shell) robi.
A jeśli chcesz sam zająć się tym specjalnym przypadkiem, zsh
ułatwia to jego (N)
kwalifikator globalny (dla noglob ), jak w przypadku (1) powyżej. fish
(przynajmniej w najnowszej wersji ) czyni to jeszcze łatwiejszym, ponieważ wykonuje ukryte polecenie dla set
polecenia. Odpowiednikiem byłoby:
set files *
if count $files > /dev/null
rm -f -- $files
end
Zobacz Dlaczego nullglob nie jest domyślny, aby uzyskać więcej informacji.
1 . Ściśle mówiąc, to dopiero sh
od czasu powłoki Bourne'a (od Unixa V7 w 1979 r.); wcześniejsze wersje sh
(które /etc/glob
wzywały nieoznaczone symbole wieloznaczne, z których pochodzi nazwa globu ) zachowywały się jak csh
lub zsh -o cshnullglob
, to znaczy /etc/glob
przerywałyby polecenie, jeśli żadna z globów nie pasowała (i tłumiłyby niepasujące globy, jeśli przynajmniej jeden z nich miał jakieś dopasowanie). Zachowanie zostało złamane przez powłokę Bourne'a.