The "colon sign" and the "dollar question mark" can be combined to check if a sh script does have an argument and assigns it directly to a variable of interest:

cmd=${1:? "Usage: $0 {build|upload|log}"}

Can someone explain step for step how this works, and where I can find the details on its implementation? For example I would like to be able to call a function instead of printing to stderr.

help() {
  echo $"Usage: $0 {build|upload|log}"
  exit 1
cmd=${1:? help}

Why is this not possible?

  • Perhaps not necessary, but just to make sure. I can just use test $1 && cmd=$1 || help which would work. My question is really about how these built-in operators combine together in the way they do, not the specific result which can obtained in many ways. – Anne van Rossum Aug 15 '14 at 11:56
  • You might get some utility out of this – mikeserv Aug 15 '14 at 15:21

This is covered in Variable expansion:


If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted.

Therefore if there is no argument with the execution of the script, then the variable cmd becomes help and is written to standard out and back to the shell.

However, it is just read in and not executed. If you surround it with backticks then it will be executed and run the Usage funtion:

help() {
  echo "Usage: $0 {build|upload|log}"
cmd=${1:? `help`}

Unfortunately, this will still present stderr, as the variable expansion is designed to.

You could alternatively, do the following:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.