我继承了一些bash代码,这两行让我感到困惑:
branch_name=`git describe --contains --all HEAD`
branch_name=${branch_name:-HEAD}
我对:
冒号运算符的理解是基于索引创建子字符串,因此在这种情况下使用字符串-HEAD
没有任何意义。
答案 0 :(得分:34)
如果已定义,则采用变量branch_name
。如果未定义,请改用HEAD
。
有关详细信息,请参阅Shell Parameter Expansion:
3.5.3 Shell参数扩展
'$'字符引入了参数扩展,命令替换或算术扩展。 ... 参数扩展的基本形式是$ {parameter} ...
当不执行子串扩展时,使用下面描述的形式(例如,': - '),Bash测试未设置或为null的参数。省略冒号只会导致对未设置的参数进行测试。换句话说,如果包含冒号,运算符将测试参数的存在性及其值不为空;如果省略冒号,则运算符仅测试是否存在。<强> $ {参数:-word} 强>
如果参数未设置或为null,则替换
word
的扩展。否则,parameter
的值将被替换。
下划线包括以下几行。两者之间的区别是
${parameter:-word}
vs
${parameter:offset}
${parameter:offset:length}
<强> $ {参数:偏移} 强>
的 $ {参数:偏移量:长度} 强>这称为子字符串扩展。它扩展为参数值的最大长度字符,从offset指定的字符开始 ...
如果offset的计算结果小于零,则该值将用作参数值末尾的字符偏移量。 ... 请注意,负偏移必须与冒号分隔至少一个空格,以避免与': - '扩展混淆。
答案 1 :(得分:15)
在这种情况下,冒号只是-
运算符的修饰符。仅当${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
答案 2 :(得分:6)
在bash中,${VAR1:-VAR2}
相当于SQL的coalesce(VAR1, VAR2)
或C#的VAR1 ?? VAR2
。
在你的情况下:
branch_name=`git describe --contains --all HEAD`
branch_name=${branch_name:-HEAD}
第一行执行git
命令并设置branch_name
变量中的值,然后,第二行合并其值,如果HEAD
则指定值branch_name
是空的。
正如您所说${VAR1:NUM}
是字符串前缀操作(SQL中为left
),当与负数一起使用时,${VAR1: -NUMBER}
成为后缀(right
)操作。注意减号前面的空格:如果你跳过那个空格,它就像我之前说的那样成为coalesce
操作。