命令中的Bash通配符(*)会导致捕获正确的输出

问题描述 投票:2回答:1

请原谅标题的措辞,我不知道如何为这个“问题”找到一个引人注目的标题。

如果我在我的终端(运行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

为什么输出会有所不同?目前,这打破了脚本的逻辑,因为它期望分支。我想避免进行冗余检查(检查这是否是一个实际的分支)如果可能的话,使脚本混乱。

编辑:我已经尝试引用*,它产生与上面相同的结果。

Visual version of the problem

git bash glob
1个回答
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*')
© www.soinside.com 2019 - 2024. All rights reserved.