EMR集群EC2实例Bootstrap脚本子进程变量未绑定问题求助
问题根源与解决方案
你的问题出在Heredoc的变量展开时机上:
- 当你使用无引号的
<< EOF时,当前shell(父脚本)会在将内容写入bootstrap.sh之前,先展开所有以$开头的变量。 - 你在父脚本里只定义了
var,没有定义intra,所以echo $intra会被父shell展开成echo(空内容)。最终生成的bootstrap.sh实际内容是:
intra="intra" echo var echo
- 如果EMR的Bootstrap环境默认开启了
set -u(严格模式,引用未定义变量直接报错),就会触发intra: unbound variable的错误——本质是父脚本提前破坏了子脚本里的变量引用逻辑。
修复方案
要让子脚本里的$intra在子进程中才展开,需要在父脚本的Heredoc里转义$intra,避免被父shell提前解析:
#!/bin/bash var="var" cat << EOF > ~/bootstrap.sh intra="intra" echo $var echo \$intra # 加反斜杠转义$,让父shell不展开该变量 EOF /bin/bash ~/bootstrap.sh exit 0
这样生成的bootstrap.sh会保留echo $intra,执行子脚本时,先定义intra="intra"再引用变量,就不会报错了。
另一种可选方案是给Heredoc的EOF加单引号,完全禁止父shell展开变量,同时通过环境变量传递var:
#!/bin/bash var="var" export var # 导出为环境变量,子进程可直接读取 cat << 'EOF' > ~/bootstrap.sh intra="intra" echo $var echo $intra EOF /bin/bash ~/bootstrap.sh exit 0
内容的提问来源于stack exchange,提问作者Oliver Sepúlveda
相关产品推荐
相关产品推荐

