Предположим, у вас есть следующие файлы :foo.abc
, bar.abc
, qux.ghi
. В bash тело цикла выполняется четыре раза :с foo.abc
, bar.abc
,*.def
(с литералом*
)и qux.ghi
. В zsh с параметрами по умолчанию цикл вообще не выполняется, вместо этого вы получаете ошибку
zsh:1: no matches found: *.def
Чтобы избежать запуска цикла с нерасширенным шаблоном подстановочных знаков и запустить цикл с существующими файлами (, если таковые имеются ), добавьте квалификаторN
glob .
for file in *.{abc,def,ghi}(N); do …
Вы также можете использовать оператор|
, чтобы иметь один паттерн вместо нескольких паттернов. (Фигурные скобки не являются шаблоном с подстановочными знаками, это просто буквальное расширение строки, которое происходит до анализа подстановочных знаков, т. е. *.{abc,def,ghi}(N)
— это просто сокращение для*.abc(N) *.def(N) *.ghi(N)
)
for file in *.(abc|def|ghi)(N); do …
Обратите внимание, что вам по-прежнему нужен квалификатор N
glob, иначе вы получите сообщение об ошибке, если ни один файл не соответствует.
Вместо использования квалификатора N
glob можно включить параметр null_glob
(setopt null_glob
). Это часто имеет смысл в сценариях. Обратите внимание, что в bash вам нужно будет активировать аналогичную опцию (shopt -s nullglob
), чтобы избежать запуска тела цикла на нерасширенных шаблонах.
How can I make command -v return the correct path
Вы не можете. Если вам нужен полный путь, используйте which
. Однако я не думаю, что вам нужен этот полный путь. Просто позвоните
command git...
без флага -v
. У флага нет интуитивного поведения, и он не выводит того, что сделал бы command
без флага.
But, if I use which instead, even after overwriting git as function, it returns the correct path.
which
— внешняя программа. Он не знает функций bash. command
является встроенным.