what is the meaning of : ${CONTAINER_CLI:="docker"} in shell scripting - bash

I am learning shell scripting and came across this line
: ${CONTAINER_CLI:="docker"}
can someone please explain me what this line do? what is the meaning of : here?

man bash command said:
${parameter:=word}
Assign Default Values.
If parameter is unset or null, the expansion of word is
assigned to parameter.
The value of parameter is then substituted.
Positional parameters and special parameters
may not be assigned to in this way.
So, the variable CONTAINER_CLI is assigned with the value docker if CONTAINER_CLI does not exists or empty.
But... if you simply write :
${CONTAINER_CLI:="docker"}
You obtain an error if the result is not a command.
You just want make a assignation.
Put simply a : before.
It's like:
CONTAINER_CLI=${CONTAINER_CLI:="docker"}

Related

What is the purpose of setting a variable default to empty in bash?

In general, this syntax is used to guarantee a value, potentially a default argument.
(from the Bash reference manual)
${parameter:-word}
If parameter is unset or null, the expansion of word is substituted.
Otherwise, the value of parameter is substituted.
What would be the purpose of defaulting a variable to empty if the substitution is only chosen when the variable is empty anyway?
For reference, I'm looking at /lib/lsb/init-functions.
"Null" means the variable has a value, and this value is an empty string. The shell knows the variable exists.
"Unset" means the variable has not been defined : it does not exist as far as the shell is concerned.
In its usual mode, the shell will expand null and unset variable to an empty string. But there is a mode (set -u) that allows the shell to throw a runtime error if a variable is expanded when it is unset. It is good practice to enable this mode, because it is very easy to simply mis-type a variable name and get difficult to debug errors.
It can actually be useful from a computing perspective to differentiate between unset and empty variables, you can assign separate semantics to each case. For instance, say you have a function that may receive an argument. You may want to use a (non-null) default value if the parameter is unset, or any value passed to the function (including an empty string) if the parameter is set. You would do something like :
my_function()
{
echo "${1-DEFAULT_VALUE}"
}
Then, the two commands below would provide different outputs:
my_function # Echoes DEFAULT_VALUE
my_function "" # Echoes an empty line
There is also a type of expansion that does not differentiate between null and not set :
"${VAR:-DEFAULT_VALUE}"
They are both useful depending on what you need.
The way to test if a variable is set or not (without running the risk of a runtime error) is the following type of expansion :
"${VAR+VALUE}"
This will expand to an empty string if VAR is unset, or to VALUE if it is set (empty or with a value). Very useful when you need it.
Generally, it is helpful to:
Declare variables explicitely
set -u to prevent silent expansion failure
Explicitly handle unset variables through the appropriate expansion
This will make your scripts more reliable, and easier to debug.

Why does : prevent ${username=`whoami`} from throwing an error?

Why does
${username=`whoami`}
throw an error, whereas
: ${username=`whoami`}
performs an assignment without any ill effects?
I understand : is a placeholder. What is its use in this command? Is it the equivalent of running : 'whoami'?
For reference, the former usage was previously referred to as #3, and the new one as #4.
${parameter=value}
does two things: It has the side effect of assigning value to parameter if parameter is not already set, and the direct effect of expanding to the value of parameter when complete.
The error is the result of that direct effect: When you run
${user=`whoami`}
...on its own line, then that expands to, and tries to run, the output of whoami as a command. Let's say that the user variable is not previously assigned to, and the output of whoami is james; it would then try to run the command james, which would throw an error.
By contrast, running
: ${user=`whoami`}
...first performs the side effect (of doing an assignment to user if user is not already set), and then runs:
: james
...which has no effect, so only the side effect (of the assignment) is performed.
In #3, according to the bash manual pages, you are trying to execute the whoami command output, i.e, if whoami command output is "peter", #3 means that the "peter" command is invoked. Moreover, "username" variable is assigned the value "peter"
The bash manual describes ${parameter:=word} as follows:
Assign Default Values. If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way.
Likewise, for the : command --
No effect; the command does nothing beyond expanding arguments and performing any specified redirections. A zero exit code is returned.

Please explain these symbols I found in a shell script

I see the following line in a shell script.
CATALINA_BASE=${CATALINA_BASE:-${APP_HOME}/tomcat}
Is the :- like an if statement? That is, if the environment variable $CATALINA_BASE exists, use its value for the variable CATALINA_BASE?
I also see this line:
APP_USER=${APP_USER:?}
What does the ? mean? In this case, there is no -.
${foo:-bar} and ${foo:bar} are both parameter expansions with defaults. They vary in terms of how they expand an explicitly-set empty string (as opposed to a null, unset string).
See http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html, http://mywiki.wooledge.org/BashFAQ/073, or http://mywiki.wooledge.org/BashSheet#Parameter_Operations for explanations of these and more.

bash: "${A:-B}" operator

I've been refactoring some bash code, and stumbled upon this bash notation:
"${string_a:-string_b}"
I've played a little with this on the command line:
$ echo "${string_a:-string_b}"
string_b
$ export string_a=string_a_value
$ echo "${string_a:-string_b}"
string_a_value
I seems that the {a:-b} notation returns the value of variable a if it is defined, or the string b otherwise.
Where can I find a more formal definition for this operator?
Peer pressure, I post my comment as an answer : )
I like this reference card: Advanced Bash-Scripting Guide , specifically in your case it will be useful "# Table B-4. Parameter Substitution and Expansion".
I do not copy any issue they indicate not to violate any copyright. Just find all information there.
Another useful link is the Shell Parameter Expansion section in the Bash Reference
Manual. The :- operator is defined as:
${parameter:-word} If parameter is unset or null, the expansion of
word is substituted. Otherwise, the value of parameter is substituted.
By the way, bash features three similar operators ${parameter:=word}, ${parameter:?word} and ${parameter:+word}, defined in that section.
You can access bash documentation using man bash. To search type /
${parameter:-word}
Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

Bash script what is := for?

Does anyone know what is := for?
I tried googling but it seems google filters all symbol?
I know the below is something like checking if the variable HOME is a directory and then something is not equal to empty string.
if [ "${HOME:=}" != "" ] && [ -d ${HOME} ]
From Bash Reference Manual:
${parameter:=word}
If parameter is unset or null, the expansion of word is assigned to
parameter. The value of parameter is
then substituted. Positional
parameters and special parameters may
not be assigned to in this way.
Basically it will assign the value of word to parameter if and only if parameter is unset or null.
From the Bash man page:
Assign Default Values. If
parameter is unset or null, the
expansion of word is assigned to
parameter. The value of parameter
is then substituted. Positional
parameters and special parameters may
not be assigned to in this way.
Man pages are a wonderful thing. man bash will tell you almost everything you want to know about Bash.

Resources