45

我继承了一些 bash 代码,这两行让我感到困惑:

branch_name=`git describe --contains --all HEAD`
branch_name=${branch_name:-HEAD}

我对:冒号运算符的理解是,它基于索引创建子字符串,因此-HEAD在这种情况下,使用字符串没有任何意义。

4

3 回答 3

52

这需要变量branch_name,如果它已定义。如果未定义,请HEAD改用。

有关详细信息,请参阅Shell 参数扩展

3.5.3 Shell参数扩展

'$' 字符引入了参数扩展、命令替换或算术扩展。...参数扩展的基本形式是${parameter}。
...
当不执行子字符串扩展时,使用下面描述的形式(例如,':-'),Bash 测试未设置或为空的参数。省略冒号会导致仅对未设置的参数进行测试。换句话说,如果包含冒号,则运算符会测试两个参数的存在以及它的值是否不为空;如果省略冒号,则运算符仅测试是否存在。

${参数:-字}

如果参数未设置或为空,word则替换为的扩展。否则,parameter替换 的值。


下面几行介绍了子字符串。两者的区别在于

${parameter:-word}

对比

${parameter:offset}
${parameter:offset:length}

${参数:偏移}
${参数:偏移:长度}

这称为子字符串扩展。它扩展到从 offset 指定的字符开始的参数值的最大长度字符。
...
如果 offset 计算为小于零的数字,则该值用作从参数值末尾开始的字符偏移量。...请注意,负偏移量必须与冒号隔开至少一个空格,以避免与 ':-' 扩展混淆。

于 2013-02-28T19:20:14.290 回答
21

在这种情况下,冒号只是-运算符的修饰符。${branch-HEAD}仅当branch未设置时才会扩展为“HEAD”,而${branch:-HEAD}如果branch也是空字符串则扩展为“HEAD”。

$ branch=master
$ echo "${branch-HEAD} + ${branch:-HEAD}"
master + master
$ branch=""
$ echo "${branch-HEAD} + ${branch:-HEAD}"
 + HEAD
$ unset branch
$ echo "${branch-HEAD} + ${branch:-HEAD}"
HEAD + HEAD
于 2013-02-28T20:12:10.223 回答
6

在 bash 中,${VAR1:-VAR2}相当于 SQLcoalesce(VAR1, VAR2)或 C# 的VAR1 ?? VAR2.

在你的情况下:

branch_name=`git describe --contains --all HEAD`
branch_name=${branch_name:-HEAD}

第一行执行git命令并设置branch_name变量中的值,然后,第二行合并其值,分配HEADifbranch_name的值为 null。

如您所说${VAR1:NUM},是字符串前缀操作(left在 SQL 中),当与负数一起使用时, as${VAR1: -NUMBER}变为后缀(right)操作。请注意减号之前的空格:如果您跳过该空格,它将成为coalesce我之前所说的操作。

于 2013-02-28T19:37:30.520 回答