2

What are : at the beginning of lines used for in a Bash script?

I have seen some usage of : at the beginning of lines, like in the following snippet of code:

cgcreate -g "$cgroups:/$uuid"
: "${BOCKER_CPU_SHARE:=512}" && cgset -r cpu.shares="$BOCKER_CPU_SHARE" "$uuid"
: "${BOCKER_MEM_LIMIT:=512}" && cgset -r memory.limit_in_bytes="$((BOCKER_MEM_LIMIT * 1000000))" "$uuid"

Experiments show that : functions much like a comment (#), since nothing is printed to stdout; however, : $(echo foo > bar) creates a new file bar, so code execution does happen.

Shuzheng
  • 4,411
  • "Code execution does happen" but not for the reason you think. : is a null command, but shell evaluates its args before doing nothing with them. However, $( .. ) is a process expansion -- the ... contents are executed to provide the arg before it is discarded. This is a known code injection attack route. – Paul_Pedant Mar 08 '21 at 16:57

1 Answers1

3
$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

It's the same command as true (except that the description given by help is different).

Notably, it's a regular command, not a syntactic element, so differs from a comment in that the rest of the command line needs to be valid shell syntax, and any expansions still take place.

E.g. in your example, "${BOCKER_CPU_SHARE:=512}" is the set-default-value expansion, it sets the variable to 512 if it's unset or empty:

$ foo=
$ : "${foo:=512}"
$ echo "$foo"
512

but

$ foo=42
$ echo ${foo:=512}       # no change since already has value
42

In a way, that expansion is short for if [ -z "$foo" ]; then foo=512; fi, but only works as an expansion, so needs some command to accompany it. And : is the one often used for that, because it doesn't do anything itself.

I'm not sure what the point of && there is, though, since : is always truthy, so that could be written as just

: "${BOCKER_CPU_SHARE:=512}"
cgset -r cpu.shares="$BOCKER_CPU_SHARE" "$uuid"

etc.

ilkkachu
  • 138,973