变量未在通过 heredoc 传递的脚本中初始化

Variable isn't initialized in script passed through heredoc

请考虑以下代码片段,它应该进入 kubernetes 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 可以被初始化并且我正在正确打印它,因为我试图将它设置为测试字符串并打印出来。

目前我有一个脚本 运行s:

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

在容器外部而不是在 "heredoc" 内部,它正确地初始化了变量。

如何使用 "heredoc" 正确初始化 bar?我道歉 对于示例的特殊性,不想丢失细节将其转换为我认为相似的而不是实际的(这里的开发人员很差)。

假设你想 运行 在你正在启动的容器中执行这个特定的 mysql 命令,运行 在这种情况下 heredoc 将对内容进行两次解析,一次由本地 shell,然后再次通过目标 shell(通过容器)。所以你需要保证本地shell做的第一级解析不会扩展变量或扩展命令替换。

你可以通过在 $ 前面加上前缀 $ 来逃避任何扩展,这意味着坚持本地 shell 推迟扩展它并让它过去并由容器内的 shell 解释。

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

或使用带有引号 de-limiter 的特殊情况的 heredoc,而不是使用 'EOF'EOF,这会禁用本地 shell 完成的任何解析。因此,使用这种方法,不再需要任何手动转义。

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