3

Setting a variable with a fallback default value works...as long as we're using the variable in a subsequent command:

$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
production
$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
staging

However, trying to set the variable immediately preceding the command that uses it behaves differently:

$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV

$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV
staging

Why the second example behaves differently?

2 Answers 2

4

Let's replace the semicolon with a newline to make the first version clearer:

APP_ENV="${APP_ENV:-production}"
echo $APP_ENV

Line 1 executes completely before the shell looks at line 2.

Line 1 causes $APP_ENV to be set equal to production.

Line 2 accesses that variable and provided its value to the echo command.

Now the single-command version:

APP_ENV="${APP_ENV:-production}" echo $APP_ENV

First the shell expands the command line according to parameter expansion and (not applicable in this case) other kinds of substitution. Since the current value of $APP_ENV is empty, that expands to:

APP_ENV="${:-production}" echo

After performing expansions, it sets the variable $APP_ENV to production for this command invocation only, and invokes echo "" with that value. But echo doesn not care that it got an environment varible $APP_ENV in its environment. It only looks at its command line, which consists of nothing. So it echoes nothing.

Here's how you prove that $APP_ENV really is being set in this case:

$ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
APP_ENV=production

In summary, your second example does not do what you thought it would do because the parameter expansion happens too soon.

1
  • Thank you for breaking that down, it makes perfect sense to me now!
    – EvanK
    Jul 16, 2015 at 18:32
-4

The second form is behaving differently because you're missing a ; after the variable initialization:

APP_ENV="${APP_ENV:-production}" echo $APP_ENV

should be:

APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
                                ^ semicolon that's missing

Fix that first, then restate your question.

1
  • 2
    Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.
    – Celada
    Jul 16, 2015 at 16:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .