Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash colon operator in variable substitution?

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.

like image 236
Gardner Bickford Avatar asked Feb 28 '13 19:02

Gardner Bickford


People also ask

What does :- mean in bash?

It's a parameter expansion, it means if the third argument is null or unset, replace it with what's after :- $ x= $ echo ${x:-1} 1 $ echo $x $

What is colon in bash script?

Description. The : (colon) command is used when a command is needed, as in the then condition of an if command, but nothing is to be done by the command. This command simply yields an exit status of zero (success). This can be useful, for example, when you are evaluating shell expressions for their side effects.

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.

What is $@ in bash?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.


2 Answers

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

See Shell Parameter Expansion for details:

3.5.3 Shell Parameter Expansion

The ‘$’ character introduces parameter expansion, command substitution, or arithmetic expansion. ... The basic form of parameter expansion is ${parameter}.
...
When not performing substring expansion, using the form described below (e.g., ‘:-’), Bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both parameter’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence.

${parameter:-word}

If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.


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

${parameter:-word} 

vs

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

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

This is referred to as Substring Expansion. It expands to up to length characters of the value of parameter starting at the character specified by offset.
...
If offset evaluates to a number less than zero, the value is used as an offset in characters from the end of the value of parameter. ... Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the ‘:-’ expansion.

like image 69
Olaf Dietsche Avatar answered Sep 19 '22 06:09

Olaf Dietsche


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 
like image 44
chepner Avatar answered Sep 23 '22 06:09

chepner