【问题标题】:Bash : improve variable indirection assignment in one lineBash:在一行中改进变量间接赋值
【发布时间】:2022-01-10 01:35:28
【问题描述】:

在我的 Gitlab 项目中,我设置了 Gitlab 变量 MY_VAR_DEVMY_VAR_PROD

根据提交分支,我希望 CI/CD 管道(.gitlab-ci.yml 文件)上有不同的行为,根据以下代码:

- if [ $CI_COMMIT_BRANCH == "dev" ]; then export ENV="DEV"; fi
- if [ $CI_COMMIT_BRANCH == "prod" ]; then export ENV="PROD"; fi
- TMP_MY_VAR="MY_VAR_${ENV}"
- export MY_VAR=$( eval echo \$$TMP_MY_VAR )
#- ... bla bla with $MY_VAR use

有没有办法合并最后两行并直接影响MY_VAR MY_VAR_${ENV} 的评估值? (我的意思是不要使用TMP_MY_VAR

感谢您的帮助:)

【问题讨论】:

  • 顺便说一句,BashFAQ #6 是该主题的综合资源。
  • 另外,[ $CI_COMMIT_BRANCH == "dev" ] 引用了完全错误的内容。健壮正确的代码看起来像[ "$CI_COMMIT_BRANCH" = dev ]——常量不需要引用;参数扩展 确实 需要引用才能正确处理所有可能的值; test 的唯一 POSIX 标准字符串比较运算符是 =,而不是 ==

标签: bash shell variables gitlab-ci indirection


【解决方案1】:

重复一下自己一点

- if [ "$CI_COMMIT_BRANCH" = "dev" ]; then MY_VAR=$MY_VAR_DEV; fi
- if [ "$CI_COMMIT_BRANCH" = "prod" ]; then MY_VAR=$MY_VAR_PROD; fi
- export MY_VAR
#- ... bla bla with $MY_VAR use

- case $CI_COMMIT_BRANCH in dev) MY_VAR=$MY_VAR_DEV ;; prod) MY_VAR=$MY_VAR_PROD ;; esac
- export MY_VAR

没有必要通过间接参数扩展使事情复杂化,特别是如果您使用的 shell 不支持它,而 eval 的使用非常脆弱。

(除非MY_VAR 被您的shell 执行的另一个程序使用,否则它不需要导出。)

【讨论】:

  • 多行大小写会更具可读性。
  • 确实如此。我不想费心记住(我认为是)YAML 文件中多行值的规则。
【解决方案2】:

这不是间接赋值,而是间接取消引用。假设 bash 4.x:

# append all-caps version of CI_COMMIT_BRANCH contents to MY_VAR_prefix
var="MY_VAR_${CI_COMMIT_BRANCH^^}"

# dereference variable created above, assign result to MY_VAR
MY_VAR=${!var}

...当然,你可以把整个事情写成一行:

var="MY_VAR_${CI_COMMIT_BRANCH^^}"; MY_VAR=${!var}

【讨论】:

    猜你喜欢
    • 2012-04-13
    • 2013-04-14
    • 2015-12-03
    • 2021-10-07
    • 2020-12-29
    • 2013-05-03
    相关资源
    最近更新 更多