Что бы вы хотели вместо этого? Не работатьrm
вообще (1)? Запустить его с буквальным *
аргументом, как в других оболочках типа Борна (2)? Запустить его без каких-либо аргументов (3)?
files=(*(N)); (($#files)) && rm -- $files
, Или (rm -- *) 2> /dev/null
это также скрыло бы подлинные ошибкиrm
которые были бы глупыми. Вы можете отменить zsh
ошибку, но восстановить stderr для rm
команды, хотя с(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
, Затем, как в случае, sh
когда zsh
теперь эмулируется для этой единственной командной строки, несоответствие *
передается как есть rm
и rm
жалуется, поскольку этот *
файл не существует. Мы подавляем rm
stderr, как вы это делаете, sh
чтобы подавить это сообщение об ошибке, но опять же, это глупо, поскольку оно скрывает подлинные ошибки, rm
в отличие от ошибки, вызванной неправильным поведением sh
передачи литерала *
вrm
. rm -f '*'
не будет жаловаться на несуществующий *
файл, так что вы можете сделатьemulate sh -c 'rm -f -- *'
rm -- *(N)
, rm
будет жаловаться , хотя , когда он не пропустил ни одного аргумента, хотя опять же , не rm -f
: rm -f -- *(N)
.
Обычно, rm -f
это команда, которую вы хотите использовать, если хотите, чтобы все файлы были удалены, и получаете сообщение об ошибке только в том случае, если файлы не могут быть удалены или IOW все еще остаются после rm
возвращения. Вы также обычно хотите использовать -f
в сценариях, чтобы пользователь не получал подсказки в некоторых ситуациях.
Здесь звонить, rm
когда шар не совпадает, неправильно. sh
1 поведение является неправильным. Это безвредно для такой модели *
, но для одной такой *.[ch]
передачи передача « *.[ch]
как есть», когда она не совпадает, может привести к*.[ch]
к ошибочному удалению файла:
$ 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
В противном случае с ошибкой самое разумное , что нужно сделать , и это то , что zsh
(и fish
, csh
, tcsh
, bash -o failglob
и оригинальный Unix оболочки) делает.
И если вы хотите позаботиться о себе в этом особом случае, zsh
упростите его с помощью (N)
квалификатора glob (для noglob ), как в случае (1) выше. fish
(по крайней мере, в последней версии ) делает это еще проще, так как это делает неявный noglob для set
команды. Итак, эквивалент там будет:
set files *
if count $files > /dev/null
rm -f -- $files
end
См. Почему nullglob не используется по умолчанию по для более подробной информации.
1 . Строго говоря, это только sh
со времен оболочки Bourne (начиная с Unix V7 в 1979 году); более ранние версии sh
(которые сделали вызов /etc/glob
на некотируемых подстановочные знаки , который где Glob название происходит от) сделали ведут себя , как csh
и zsh -o cshnullglob
, что /etc/glob
бы прервать команду , если ни один из комков не был ни одного матч (и будет подавлять несовпадающих шарики , если по крайней мере , у одного из них был какой-либо матч). Поведение было нарушено оболочкой Борна.