Что бы вы хотели сделать вместо этого? Не запускать 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
эмулировать sh -c 'rm - *' 2> / dev / null
. Затем, как и в sh
, который zsh
теперь эмулирован для этой единственной командной строки, несоответствие *
передается как есть в rm
и rm
жалуется, что файл *
не существует.Мы подавляем stderr rm
, как и в sh
, чтобы подавить это сообщение об ошибке, но, опять же, это глупо, поскольку оно скрывает подлинные ошибки с помощью rm
как в отличие от ошибки, вызванной неправильным поведением sh
при передаче буквального *
в rm
. rm -f '*'
не будет жаловаться на несуществующий файл *
, поэтому вы можете эмулировать 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
прервет команду, если ни один из глобусов не найдет совпадения (и подавит несоответствующие глобусы, если хотя бы у одного из них было хоть какое-то совпадение). Поведение было нарушено оболочкой Bourne.