Bash: улучшить присвоение косвенных переменных в одной строке

#bash #shell #variables #gitlab-ci #indirection

#bash #оболочка #переменные #gitlab-ci #косвенность

Вопрос:

В моем проекте Gitlab я устанавливаю переменные Gitlab MY_VAR_DEV и MY_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
 

Есть ли способ объединить последние 2 строки и напрямую повлиять на MY_VAR значение оценки MY_VAR_${ENV} ? (Я имею в виду отсутствие использования TMP_MY_VAR )

Спасибо за вашу помощь 🙂

Комментарии:

1. Кстати, BashFAQ # 6 является исчерпывающим источником по этому вопросу.

2. Еще в сторону, [ $CI_COMMIT_BRANCH == "dev" ] цитирует совершенно не то, что нужно. Надежно корректный код будет выглядеть [ "$CI_COMMIT_BRANCH" = dev ] следующим образом: константа не нуждается в кавычках; расширение параметра требует кавычек для правильной работы со всеми возможными значениями; и единственный оператор сравнения строк POSIX для test is = , not == .


Ответ №1:

Это не косвенное присвоение, это косвенное разыменование. Предполагая, что 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}
 

Ответ №2:

Есть кое-что, что нужно сказать, чтобы немного повториться.

 - 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
 

Нет необходимости усложнять ситуацию с косвенным расширением параметров, особенно если вы используете оболочку, которая не поддерживает ее без чрезвычайно хрупкого использования eval .

(Если MY_VAR он не используется другой программой, выполняемой вашей оболочкой, его не нужно экспортировать.)

Комментарии:

1. многострочный регистр был бы немного более читабельным.

2. Действительно. Я не хотел утруждать себя запоминанием правил для многострочных значений в (как я полагаю) файле YAML.