设置具有后备默认值的变量是有效的......只要我们在随后的命令:
$ 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
但是,尝试设置变量紧接在前使用它的命令的行为有所不同:
$ 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
为什么第二个例子的行为不同?
答案1
让我们用换行符替换分号,以使第一个版本更清晰:
APP_ENV="${APP_ENV:-production}"
echo $APP_ENV
第 1 行在 shell 查看第 2 行之前完全执行。
第 1 行导致$APP_ENV
设置等于production
。
第 2 行访问该变量并将其值提供给echo
命令。
现在是单命令版本:
APP_ENV="${APP_ENV:-production}" echo $APP_ENV
首先,shell 根据参数扩展和(在本例中不适用)其他类型的替换来扩展命令行。由于 的当前值为$APP_ENV
空,因此扩展为:
APP_ENV="${:-production}" echo
执行扩展后,它将变量设置$APP_ENV
为production
仅用于此命令调用,并echo ""
使用该值进行调用。但echo
并不关心它$APP_ENV
的环境中有一个环境变量。它只查看其命令行,其中不包含任何内容。所以它没有任何回声。
以下是如何证明$APP_ENV
在这种情况下确实已设置的方法:
$ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
APP_ENV=production
总之,您的第二个示例没有执行您想象的操作,因为参数扩展发生得太快。
答案2
;
第二种形式的行为有所不同,因为变量初始化后缺少 a :
APP_ENV="${APP_ENV:-production}" echo $APP_ENV
应该:
APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
^ semicolon that's missing
先解决这个问题,然后再重申你的问题。