我必须在bash
shell 中使用环境变量并且:
echo $ENV
解析为或DEV
,具体取决于堆栈。STAGE
PRD
echo $DEV_ACCOUNT
解析为一个数字,例如echo $DEV_ACCOUNT
给出12345678
我需要echo $ENV_ACCOUNT
在应该解析为的命令中使用12345678
,但它解析为DEV_ACCOUNT
而不是12345678
。
我正在使用的命令:
aws events put-targets --rule {{ stack_name | lower }}-hello-world \
--targets "Id"="1","Arn"="arn:aws:lambda:us-west-2:$ENV_ACCOUNT:function:hello-world"
正在$ENV_ACCOUNT
解决DEV_ACCOUNT
而不是12345678
。预期输出是:
aws events put-targets --rule {{ stack_name | lower }}-hello-world \
--targets "Id"="1","Arn"="arn:aws:lambda:us-west-2:12345678:function:hello-world"
我究竟做错了什么?
答案1
请注意,大写变量名通常不能安全使用。 $ENV
例如,在许多 shell 中都是特殊的。在这些 shell 中,它的值应该是在启动某些类型的 shell 之前将获取的文件的路径名。 shell在 POSIX 模式下bash
使用。$ENV
所以,在bash
:
declare -A account
account["develop"]=12345678
account["staging"]=9128312
account["production"]=123123
mode=$run_mode
aws events put-targets \
--rule {{ stack_name | lower }}-hello-world \
--targets "Id"="1","Arn"="arn:aws:lambda:us-west-2:${account[$mode]}:function:hello-wolrd"
这将设置一个关联数组 ,account
用于保存开发、登台和生产模式的数据。然后,它定义我们正在使用的模式,并使用数组中的正确数据执行命令account
。假定该run_mode
变量是包含字符串develop
、staging
或之一的环境变量production
。
关联数组是在bash
4.0 中引入的。
我已经使用了您aws
编写的命令(除了添加换行符和我的account
变量),即使它{{ stack_name | lower }}-hello-world
可能不符合您的预期(它会尝试lower
作为命令执行)。因为我不知道aws
,所以我不知道它应该是什么样子,但它可能应该被引用。
寻址用户 mosvy 在评论中的担忧:如果变量DEV_ACCOUNT
等是环境变量,则必须根据变量的内容选择正确的变量ENV
:
declare -A account
account["DEV"]=$DEV_ACCOUNT
account["STAGE"]=$STAGE_ACCOUNT
account["PRD"]=$PRD_ACCOUNT
mode=$ENV
# the rest as before
答案2
我会重复一下善知识说关于在 shell 脚本中不使用全部大写的变量名。这通常是一个坏主意,当变量名称与默认环境变量冲突时可能会导致问题。我也同意,最好的方法是使用关联数组,正如他在答案中所描述的那样。
无论如何,如果您坚持以这种(错误)方式而不是使用数组来执行此操作,则需要执行以下操作:
varname="$env"_account
aws events put-targets --rule {{ stack_name | lower }}-hello-world \
--targets "Id"="1","Arn"="arn:aws:lambda:us-west-2:${!varname}:function:hello-world"
该${!var}
语法将扩展为名为 的变量的值var
。例如:
$ foo="foovar"
$ bar=foo
$ echo ${!bar}
foovar
但说真的,不要这样做。它复杂、繁琐、难以阅读、难以维护,而关联数组将为您解决所有这些问题。
答案3
感谢所有为我的问题发布解决方案的人。我已经实现了 bash 数组来解决我的问题。但是,我的朋友建议了一个简单的解决方案
printenv `echo $ENV`_ACCOUNT
解决了我的问题。