Bash:在一行中改进变量间接赋值

Posted

技术标签:

【中文标题】Bash:在一行中改进变量间接赋值【英文标题】:Bash : improve variable indirection assignment in one line 【发布时间】: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 标准字符串比较运算符是 =,而不是 == 【参考方案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

【讨论】:

以上是关于Bash:在一行中改进变量间接赋值的主要内容,如果未能解决你的问题,请参考以下文章

C 语言指针间接赋值 ( 直接修改 和 间接修改 指针变量 的值 | 在函数中 间接修改 指针变量 的值 | 在函数中 间接修改 外部变量 的原理 )

C 语言指针间接赋值 ( 直接赋值 和 间接赋值 | 在子函数中间接赋值 )

C 语言指针间接赋值 ( 间接赋值三要素 | 间接赋值 使用的三种场景 )

变量的直接赋值和间接赋值

C 语言指针间接赋值 ( 指针作为 函数参数 的意义 | 间接赋值 代码示例 )

Go基础指针地址间接赋值