Вы пытаетесь удалить все в текущем каталоге? Каков текущий каталог?
cutrightjm
Вы можете использовать setopt extended_glob(или даже просто rm * >/dev/null 2>&1), но на самом деле вы должны сделать обходной путь, чтобы не нуждаться rm *, это совершенно опасно
горький
Вы должны действительно опускаться, /dev/nullа не потом dev/zero. Кроме того, ваше перенаправление stderr отсутствует &; так и должно быть 2>&1.
Ройма
Сообщение об ошибке генерируется zshво время оценки команды, а не во время выполнения самой команды (из-за ошибки команда даже не выполняется). Перенаправление вывода здесь влияет только на вывод команды, а не на саму оболочку.
Adaephon
Ответы:
42
Это поведение контролируется nomatchопцией Zsh . По умолчанию, если командная строка содержит выражение globbing, которое ничего не соответствует, Zsh выведет сообщение об ошибке, которое вы видите, и не выполнит команду вообще. Вы можете отключить это, запустив
setopt +o nomatch
Затем, выражения-глобусы, которые ничего не соответствуют, будут оставлены как есть, и вы получите сообщение об ошибке rm(которое можно отключить -f, хотя это плохая идея, так как это приведет к удалению в других ситуациях, когда вы не можете хочу).
Поведение также контролируется параметрами nullglobи cshnullglob. Если nullglobустановлено и соответствующий файл не найден, шаблон удаляется из списка аргументов, а не генерирует ошибку. Настройка cshnullglobимеет аналогичный эффект, если все шаблоны в команде не совпадают, и в этом случае будет сообщено об ошибке. Примечание: настройка nullglobили cshnullglobпереопределение nomatch. Можно также установить nullglobдля отдельных моделей с помощью Глоб спецификатора N: rm *(N).
Adaephon
nomatchэто не идеал, это то, что делают Bourne-подобные оболочки. Если шаблон не совпадает, он передается как есть rm(!) , Что rmприведет к ошибке, или, что еще хуже, может удалить неправильный файл для шаблона, *.[ch]например,!
Стефан
9
Что бы вы хотели вместо этого? Не работать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
1 . Строго говоря, это только shсо времен оболочки Bourne (начиная с Unix V7 в 1979 году); более ранние версии sh(которые сделали вызов /etc/globна некотируемых подстановочные знаки , который где Glob название происходит от) сделали ведут себя , как cshи zsh -o cshnullglob, что /etc/globбы прервать команду , если ни один из комков не был ни одного матч (и будет подавлять несовпадающих шарики , если по крайней мере , у одного из них был какой-либо матч). Поведение было нарушено оболочкой Борна.
Я думаю, что он ожидает получить сообщение об ошибке, rmа не из оболочки. Что-то вроде "rm: не может удалить` * ': нет такого файла или каталога ".
Эммануэль
@ Эммануэль, тогда это 2: emulate sh -c 'rm -- *'чтобы получить (ошибочное ИМО) поведение оболочки Борна.
Стефан Шазелас
@ Stephane_Chazelas, как написано, 2 является правильным ответом на вопрос, который он не задавал :).
Эммануэль
@ Эммануэль, все 3 отвечают на вопрос: как избавиться от ошибки «Нет совпадения». Код ОП подавляет rmошибки. Это то, что вы будете делать в других оболочках, чтобы подавить ошибку, когда нет соответствующего файла, и это также приведет к подавлению подлинных ошибок rm. Мой ответ обрисовывает в общих чертах это и, мы надеемся, показывает, как поведение zsh предпочтительнее.
setopt extended_glob
(или даже простоrm * >/dev/null 2>&1
), но на самом деле вы должны сделать обходной путь, чтобы не нуждатьсяrm *
, это совершенно опасно/dev/null
а не потомdev/zero
. Кроме того, ваше перенаправление stderr отсутствует&
; так и должно быть2>&1
.zsh
во время оценки команды, а не во время выполнения самой команды (из-за ошибки команда даже не выполняется). Перенаправление вывода здесь влияет только на вывод команды, а не на саму оболочку.Ответы:
Это поведение контролируется
nomatch
опцией Zsh . По умолчанию, если командная строка содержит выражение globbing, которое ничего не соответствует, Zsh выведет сообщение об ошибке, которое вы видите, и не выполнит команду вообще. Вы можете отключить это, запустивЗатем, выражения-глобусы, которые ничего не соответствуют, будут оставлены как есть, и вы получите сообщение об ошибке
rm
(которое можно отключить-f
, хотя это плохая идея, так как это приведет к удалению в других ситуациях, когда вы не можете хочу).источник
nullglob
иcshnullglob
. Еслиnullglob
установлено и соответствующий файл не найден, шаблон удаляется из списка аргументов, а не генерирует ошибку. Настройкаcshnullglob
имеет аналогичный эффект, если все шаблоны в команде не совпадают, и в этом случае будет сообщено об ошибке. Примечание: настройкаnullglob
илиcshnullglob
переопределениеnomatch
. Можно также установитьnullglob
для отдельных моделей с помощью Глоб спецификатораN
:rm *(N)
.nomatch
это не идеал, это то, что делают Bourne-подобные оболочки. Если шаблон не совпадает, он передается как естьrm
(!) , Чтоrm
приведет к ошибке, или, что еще хуже, может удалить неправильный файл для шаблона,*.[ch]
например,!Что бы вы хотели вместо этого? Не работать
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]
к ошибочному удалению файла:В противном случае с ошибкой самое разумное , что нужно сделать , и это то , что
zsh
(иfish
,csh
,tcsh
,bash -o failglob
и оригинальный Unix оболочки) делает.И если вы хотите позаботиться о себе в этом особом случае,
zsh
упростите его с помощью(N)
квалификатора glob (для noglob ), как в случае (1) выше.fish
(по крайней мере, в последней версии ) делает это еще проще, так как это делает неявный noglob дляset
команды. Итак, эквивалент там будет:См. Почему nullglob не используется по умолчанию по для более подробной информации.
1 . Строго говоря, это только
sh
со времен оболочки Bourne (начиная с Unix V7 в 1979 году); более ранние версииsh
(которые сделали вызов/etc/glob
на некотируемых подстановочные знаки , который где Glob название происходит от) сделали ведут себя , какcsh
иzsh -o cshnullglob
, что/etc/glob
бы прервать команду , если ни один из комков не был ни одного матч (и будет подавлять несовпадающих шарики , если по крайней мере , у одного из них был какой-либо матч). Поведение было нарушено оболочкой Борна.источник
rm
а не из оболочки. Что-то вроде "rm: не может удалить` * ': нет такого файла или каталога ".emulate sh -c 'rm -- *'
чтобы получить (ошибочное ИМО) поведение оболочки Борна.rm
ошибки. Это то, что вы будете делать в других оболочках, чтобы подавить ошибку, когда нет соответствующего файла, и это также приведет к подавлению подлинных ошибок rm. Мой ответ обрисовывает в общих чертах это и, мы надеемся, показывает, как поведение zsh предпочтительнее.