Bash colon operator in variable substitution?

2019-02-03 04:09发布

问题:

I inherited some bash code and these two lines are bewildering me:

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

My understanding of the : colon operator is that is creates a substring based on an index so using a string, -HEAD in this case, does not make any sense.

回答1:

This takes the variable branch_name, if it is defined. If it is not defined, use HEAD instead.

See Shell Parameter Expansion for details.

Substrings are covered a few lines below. The difference between the two is

${parameter:-word}

vs

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


回答2:

In this case, the colon is just a modifier for the - operator. ${branch-HEAD} would expand to "HEAD" only if branch is unset, while ${branch:-HEAD} expands to "HEAD" if branch is the null string as well.

$ 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


回答3:

In bash, ${VAR1:-VAR2} is equivalent to SQL's coalesce(VAR1, VAR2), or C#'s VAR1 ?? VAR2.

In your case:

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

The first line executes the git command and sets the value in the branch_name variable, then, the second line coalesces its value assigning the value of HEAD if branch_name is null.

As you said ${VAR1:NUM} is a string prefix operation (left in SQL), which when used with a negative number, as ${VAR1: -NUMBER} becomes a suffix (right) operation. Note the whitespace before the minus sign: if you skip that whitespace it becomes the coalesce operation as I've said before.