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

时间:2019-06-25 10:56:37

标签: bash 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可以初始化,并且在尝试将其设置为测试字符串并打印出来时,我可以正确打印它。

当前,我有一个运行的脚本:

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

在容器外部而不是在“ heredoc”内部,它将正确初始化变量。

如何使用“ heredoc”正确初始化栏?我道歉  对于该示例的特定性,不希望丢失将其转换为我认为相似而不是实际的细节的细节(此处可怜的开发人员)。

1 个答案:

答案 0 :(得分:1)

假设您要在要启动的容器内运行此特定mysql命令,在这种情况下运行Heredoc将对内容进行两次解析,一次是由本地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 发生的任何扩展来做到这一点,这意味着坚持使用本地shell推迟扩展并让其通过并由shell内部的解释容器。

EOF

或在带有引号的定界符的特殊情况下使用Heredoc,而不是使用'EOF'的{​​{1}}来禁用由本地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