Переменная не инициализируется в скрипте, переданном через heredoc - PullRequest
1 голос
/ 25 июня 2019

Пожалуйста, рассмотрите следующий фрагмент, который должен войти в контейнер pubernetes mysql pod и инициализировать переменную BAR в список баз данных mysql.

kubectl -n somens exec -i mysql-69df7d4c77-hxtng bash <<EOF
echo Hello;
BAR=$(echo "show databases" | mysql -u root -pwhatever)
echo "BAR=\$BAR"
EOF 

Если я изменю строку

 BAR=$(echo "show databases" | mysql -u root -pwhatever)

на

echo "show databases" | mysql -u root -pwhatever

Я получу распечатанный список баз данных при выполнении всего фрагмента.

Когда я запускаю оригинал, я получаю пустую переменную BAR.

Теперь я знаю, что BAR можно инициализировать, и я печатаю его правильно, так как я пытался установить егопроверить строку и распечатать.

В настоящее время у меня есть скрипт, который запускается:

BAR=$(echo "show databases" | mysql -u root -pwhatever)

вне контейнера, а не внутри "heredoc", и правильно инициализирует переменную.

Как правильно инициализировать панель с помощью "heredoc"?Я извиняюсь за специфичность примера, не хотел бы потерять детали, преобразуя его в то, что, по моему мнению, похоже, а не в то, чем оно является на самом деле (бедный разработчик здесь).

1 Ответ

1 голос
/ 25 июня 2019

Предполагая, что вы хотите запустить эту конкретную команду mysql внутри контейнера, который вы запускаете, при выполнении heredoc в этом случае содержимое будет проанализировано дважды, один раз локальной оболочкой, затем снова целевой оболочкой (над контейнером).).Таким образом, вы должны убедиться, что первый уровень синтаксического анализа, выполняемый локальной оболочкой, не раскрывает переменные и не расширяет подстановки команд.

Вы можете сделать это, избежав любых расширений, происходящих с $, добавив к ним префикс \$, что означает настаивать на том, чтобы локальная оболочка откладывала расширение и позволяла ей проходить и интерпретироваться оболочкой внутри контейнера.

kubectl -n somens exec -i mysql-69df7d4c77-hxtng bash <<EOF
echo Hello;
BAR=\$(echo "show databases" | mysql -u root -pwhatever)
echo "BAR=\$BAR"
EOF

или использовать heredoc для особого случая с указанным ограничителем,вместо EOF используется 'EOF', что отключает любой анализ, выполняемый локальной оболочкой.Таким образом, при таком подходе любое ручное экранирование больше не требуется.

kubectl -n somens exec -i mysql-69df7d4c77-hxtng bash <<'EOF'
echo Hello;
BAR=$(echo "show databases" | mysql -u root -pwhatever)
echo "BAR=$BAR"
EOF
...