变量替换中的Bash冒号运算符?

时间:2013-02-28 19:18:49

标签: string bash variables colon variable-subsitution

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

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

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

3 个答案:

答案 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操作。