15

I've come across a script that uses

VAR1=${1:-8}

VAR2=${2:-4}

I can see from some other questions and playing with some code that

VAR1=${VAR2:-8}

will create VAR1 with a value of whatever VAR2 is, if it exists. If VAR2 is unset, then VAR1 will default to value 8, and VAR2 will remain unset. That is, after this command, echo VAR2 will not return anything.

So then, my question is what the first line of code does. Since variable names cannot begin with numbers, VAR1 is clearly not being set to 1 or any variable named 1. Surely there is reason for this, and it's not just a bit of pointless obfuscation?

barriboy
  • 375

2 Answers2

20

The variables used in ${1:-8} and ${2:-4} are the positional parameters $1 and $2. These hold the values passed to the script (or shell function) on the command line. If they are not set or empty, the variable substitutions you mention will use the default values 8 and 4 (respectively) instead.

This could possibly be used in a shell script or in a shell function that takes (at least) two command-line arguments, to which you'd like to provide default values if they are not provided.

A script or shell function can take any number of arguments, and these may be referenced by using $1, $2, ..., in the script or function. To get the values of the positional parameters above 9, one needs to write ${10}, ${11} etc.

Another useful variable substitution in this case is ${parameter:?word} which will display word as an error (and exit the script) if parameter is unset:

$ cat script.sh
#!/bin/bash
var1="${1:?Must provide command line argument}"
printf 'I got "%s"\n' "$var1"
$ ./script.sh
script.sh: line 3: 1: Must provide command line argument
$ ./script.sh "Hello world."
I got "Hello world."
Kusalananda
  • 333,661
  • Ah, I see. So positional parameters are a way to pass additional information to a script, like arguments in a function. Thanks. I'm not sure why that wasn't getting through my head. – barriboy Jan 17 '17 at 20:56
  • @barriboy Ah, yes. I take that sort of stuff for granted, but I shouldn't. I will add it in my answer. – Kusalananda Jan 17 '17 at 21:03
  • @Kusalananda why is the - needed? What does the minus even mean? – gMale May 06 '22 at 02:11
  • 1
    @gMale It's part of the syntax: ${var:-word} expands to word if $var is unset or empty; otherwise, it expands to $var. ${var:+word} expands to word if $var is set and not empty; otherwise, it expands to the empty string. ${var:?word} generates an error containing word and terminates if $var is unset or empty; otherwise, it expands to $var. See also the POSIX standard and your shell's manual. – Kusalananda May 06 '22 at 05:56
10

It refers to the positional parameters $1 ... $n.

${1:-default} means "if parameter 1 is unset or empty, then use default instead".

Caveat: do not confuse ${1:-2} with ${1: -2}. With bash, the latter is substituted with the last two characters of $1.

Example:

$ set --
$ echo "${1:-2}"
2

$ set 345 678
$ echo "${1:-2}"
345

$ echo "${1: -2}"
45
xhienne
  • 17,793
  • 2
  • 53
  • 69