Я пытаюсь запустить find
и исключить несколько каталогов, перечисленных в массиве. Я нахожу некоторые странное поведение, когда она расширяется, хотя, что вызывает у меня вопросы:Расширяемая звездочка в bash
~/tmp> skipDirs=("./dirB" "./dirC")
~/tmp> bars=$(find . -name "bar*" -not \(-path "${skipDirs[0]}/*" $(printf -- '-o -path "%s/\*" ' "${skipDirs[@]:1}") \) -prune); echo $bars
./dirC/bar.txt ./dirA/bar.txt
Это не пропустить dirC
как я Уолд ожидал. Проблема заключается в том, что печать расширяет котировки вокруг "./dirC"
.
~/tmp> set -x
+ set -x
~/tmp> bars=$(find . -name "bar*" -not \(-path "${skipDirs[0]}/*" $(printf -- '-o -path "%s/*" ' "${skipDirs[@]:1}") \) -prune); echo $bars
+++ printf -- '-o -path "%s/*" ' ./dirC
++ find . -name 'bar*' -not '(' -path './dirB/*' -o -path '"./dirC/*"' ')' -prune
+ bars='./dirC/bar.txt
./dirA/bar.txt'
+ echo ./dirC/bar.txt ./dirA/bar.txt
./dirC/bar.txt ./dirA/bar.txt
Если я пытаюсь удалить кавычки в $(print..)
, то *
получает расширена сразу, что также дает неправильные результаты. Наконец, если я удалю кавычки и попытаюсь избежать *
, тогда escape-символ \
будет включен как часть имени файла в поиске, и это тоже не сработает. Мне интересно, почему это не работает, и что будет работать? Я стараюсь избегать использования eval
, если это возможно, но в настоящее время я не вижу пути вокруг него.
Примечание: Это очень похоже на: Finding directories with find in bash using a exclude list, однако опубликованные решения этого вопроса, похоже, имеют проблемы, перечисленные выше.
Небольшое изменение той же проблемы http://stackoverflow.com/q/28682013/45375 – mklement0