Bash 命令中的通配符 (*) 导致捕获正确的输出
Bash wildcard (*) in command causes in correct output to be captured
请原谅标题的措辞,我不确定如何为这个标题起一个朗朗上口的标题'issue'。
如果我 运行 在我的终端中执行以下命令 (运行 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
它似乎采用 *
并回显找到的分支以及我当前工作目录中的每个 file/directory 名称。
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...)
在存储到您的数组之前会进行路径名扩展。 * branchname
标记 git
中的当前分支。当构造数组 branches
时,git
命令输出中的 *
扩展为当前目录中的所有文件。
您可以使用 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
结合使用。这也将 trim 前导空格。如果不需要,请使用 IFS= read -r ...
:
branches=()
while read -r branch; do
branches+=("$branch")
done < <(git branch --list '[rR]elease*')
请原谅标题的措辞,我不确定如何为这个标题起一个朗朗上口的标题'issue'。
如果我 运行 在我的终端中执行以下命令 (运行 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
它似乎采用 *
并回显找到的分支以及我当前工作目录中的每个 file/directory 名称。
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...)
在存储到您的数组之前会进行路径名扩展。 * branchname
标记 git
中的当前分支。当构造数组 branches
时,git
命令输出中的 *
扩展为当前目录中的所有文件。
您可以使用 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
结合使用。这也将 trim 前导空格。如果不需要,请使用 IFS= read -r ...
:
branches=()
while read -r branch; do
branches+=("$branch")
done < <(git branch --list '[rR]elease*')