Если есть сомнения, используйте функцию вместо. Предполагая, что у вас есть GNU, а не BSD xargs
:
# this runs not just on zsh, but also on ksh/bash/etc with GNU xargs.
# (would be POSIX-compliant but for $'\n' syntax for literal newlines)
grmci() {
{
git ls-files -i --exclude-from=.gitignore |
xargs --no-run-if-empty -d $'\n' \
git rm --cached
} >/dev/null 2>&1
}
... или, полагаясь на оболочку, чтобы выполнить больше работы и не зависеть от xargs вообще:
# this is zsh-only code; 1-indexed arrays and `(@f)...` parameterization are zsh-isms
grmci() {
{
array_of_lines=("${(@f)$(git ls-files -i --exclude-from=.gitignore)}")
{ (( ${#array_of_lines[@]} )) && [[ ${array_of_lines[1]} != '' ]]; } ||
return 0
git rm --cached -- "${array_of_lines[@]}"
} >/dev/null 2>&1
}
Обратите внимание, что ни в одном из случаев мы не используем $(git ls-files ...)
напрямую в качестве аргумента git rm --cached
; Это ведет себя неправильно, когда файлы содержат пробелы, символы глобуса и т. д. c. в их именах. (Код, который мы имеем сейчас, не допускает имен файлов с буквенными символами новой строки, но не допускает и git
).