Извините за формулировку названия, я не знаю, как сделать броское название для этой «проблемы».

Если я запустил следующую команду в своем терминале (Запуск MacOS Sierra 10.12.6) git branch --list [rR]elease*

Это дает следующий ожидаемый результат

* Release-x
  release-1
  release-2
  release-3

Однако, если я вставлю следующее в сценарий bash

branches=($(git branch --list [rR]elease*))

for branch in "${branches[@]}"
do
  echo "Found branch $branch"
done

Кажется, он берет * и повторяет найденные ветки и имя каждого файла / каталога в моем текущем рабочем каталоге.

Found branch README.md
Found branch acceptance-test
Found branch build
Found branch build.gradle
Found branch flow.sh
Found branch gradle
Found branch gradle.properties
Found branch gradlew
Found branch gradlew.bat
Found branch performance-tests
Found branch postman
Found branch service
Found branch settings.gradle
Found branch sonar-project.properties
Found branch Release-x
Found branch release-1
Found branch release-2
Found branch release-3

Почему выходы различаются? В настоящее время это нарушает логику сценария, поскольку он ожидает ветвей. Я хочу избежать избыточных проверок (проверьте, действительно ли это ветвь), загромождающих скрипт, если это возможно.

Изменить: я попытался процитировать *, и он дает тот же результат, что и выше.

Визуальная версия проблемы

2
Chris Edwards 28 Дек 2017 в 13:54

1 ответ

Лучший ответ

$(git...) подвергается расширению имени пути перед сохранением в вашем массиве. * branchname отмечает текущую ветвь в git. Этот * в выводе команды git расширяется на все файлы в вашем текущем каталоге при построении массива branches.

Вы можете отключить раскрытие имени пути с помощью set -f. Кроме того, вы должны установить $IFS только на <newline>, иначе строки с пробелом будут разделены на несколько элементов (*<space>branchname станут * и branchname ):

old_IFS=$IFS
IFS=$'\n'   
set -f
branches=($(git branch --list '[rR]elease*'))    
set +f   
IFS=$old_IFS

Или лучше использовать readarray:

readarray -t branches < <(git branch --list '[rR]elease*')

Или вы можете использовать цикл while с read. Это также обрежет ведущие пробелы. Если это нежелательно, используйте IFS= read -r ...:

branches=()
while read -r branch; do
    branches+=("$branch")
done < <(git branch --list '[rR]elease*')
1
PesaThe 28 Дек 2017 в 12:21