使用Bash -s与HereDoc时变量赋值失效问题咨询
HereDoc场景下变量赋值失效的原因
问题根源是shell变量的展开时机不一样,咱们拆成两种情况说:
管道场景为啥正常
执行echo 'ASD=123; echo $ASD hi' | bash -s时:
- 单引号会拦住当前shell,不让它解析里面的
$ASD,整串命令原封不动传给bash子进程 - 子进程运行时,先完成
ASD=123的赋值,再解析$ASD得到123,最终输出123 hi
HereDoc场景为啥出问题
默认写法的HereDoc:
bash -s <<EOF ASD=123; echo $ASD hi EOF
- 因为分界符
EOF没加引号,当前shell会先把HereDoc里所有变量解析一遍,再把内容传给bash子进程 - 当前shell里根本没定义过
ASD变量,所以$ASD直接被解析成空字符串,传到子进程的内容就变成了ASD=123; echo hi - 子进程运行时,虽然完成了ASD赋值,但
echo的参数里已经没有$ASD了,自然只输出hi
你提到给$ASD加单引号后输出 hi,大概率是写法有误——如果在HereDoc里写echo '$ASD' hi,当前shell会把单引号里的内容当作普通字符串,传到子进程的是ASD=123; echo '$ASD' hi,子进程运行时单引号会拦住变量解析,应该输出$ASD hi才对。不过不管怎样,核心都是变量解析时机的问题。
怎么解决
要让HereDoc里的变量在子进程中解析,只要给分界符加单引号,让当前shell别碰里面的内容就行:
bash -s <<'EOF' ASD=123; echo $ASD hi EOF
这样当前shell会原封不动把内容传给子进程,子进程先赋值再解析变量,就能得到预期的123 hi
内容的提问来源于stack exchange,提问作者The Bic Pen
相关产品推荐
相关产品推荐

