Что бы вы хотели вместо этого? Не работать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жалуется, поскольку этот *файл не существует. Мы подавляем rmstderr, как вы это делаете, 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когда шар не совпадает, неправильно. sh1 поведение является неправильным. Это безвредно для такой модели *, но для одной такой *.[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бы прервать команду , если ни один из комков не был ни одного матч (и будет подавлять несовпадающих шарики , если по крайней мере , у одного из них был какой-либо матч). Поведение было нарушено оболочкой Борна.