basos
basos

Reputation: 576

Combine bash variable and parameter expansion on same command

In a bash shell I tried the following 2 commands producing different effects:

$ a=`echo UPDATED` echo ${a:-DEFAULT}
DEFAULT

$ a=`echo UPDATED`; echo ${a:-DEFAULT}
UPDATED

Isn't possible to achive the result in one command (first case) ? And if not, why?

Some quotes from the man:

A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator.

Expansion is performed on the command line after it has been split into words.

For clarity, the real wold case involves providing a binary to be executed by an event handler. The binary path is got from a configuration file, falling back to default if not defined in the configuration file.

Something closer to real case is this snippet, that is called by event handler:

a=`getConfigVariable "myExec"` ${a:-/opt/bin/default}

Where getConfigVariable "myExec" returns the configuration variable "myExec", or an empty string if it is not defined. For example:

$ getConfigVariable "myExec"
/opt/bin/updated

Upvotes: 3

Views: 394

Answers (2)

tripleee
tripleee

Reputation: 189936

The shell parses the command line before executing any of it.

In other words, ${a:-DEFAULT} is evaluated before a=UPDATED is assigned.

(Notice also how this rearticulation of the assignment avoids the useless use of echo.)

Chapter 3.5 of the Bash Reference Manual has a detailed account of in which order a command line gets parsed. You will notice that parameter expansion is near the beginning, after tilde and brace expansion.

Upvotes: 5

anubhava
anubhava

Reputation: 786261

You may use:

a=$(echo UPDATED) bash -c 'echo "${a:-DEFAULT}"'

UPDATED

bash -c will fork a new sub-shell that has inline value of a available.

Note that a=$(echo UPDATED) is meaningless unless you have some other command substitution there. It can be shortened to:

a='UPDATED' bash -c 'echo "${a:-DEFAULT}"'

Upvotes: 2

Related Questions