使用此处文档从 Bash 脚本创建脚本;为什么我的变量被替换了?

使用此处文档从 Bash 脚本创建脚本;为什么我的变量被替换了?

我在从主脚本创建脚本时遇到问题:

很简单:

cat  pippo << EOF
LOGFILE=test.log    
echo '#############################' >> $LOGFILE
EOF

。但是,当我检查 pippo 时,我得到:

LOGFILE=test.log
echo '#############################' >>
EOF

为什么 $LOGFILE 被替换了?

答案1

默认情况下,此处文档受 shell 扩展、精确参数扩展、命令替换和算术扩展的影响。因此,在您的情况下正在发生变量(参数)扩展 - 变量LOGFILE正在当前 shell 中扩展,并且由于该变量可能不存在,因此 null 将作为扩展值返回(并替换)。

要在此处文档中逐字获取 shell 元字符,请在终止符字符串周围使用引号:

cat pippo <<'EOF'  ## "EOF" would do too
LOGFILE=test.log    
echo '#############################' >>"$LOGFILE"
EOF

还要引用变量扩展,因为(大概)它引用文件名,因此扩展后不会对其进行分词和路径名扩展。

答案2

要真正拥有一个pippo文件,您需要执行以下操作:

cat > pippo <<EOF

它将此处文档中的值重定向到名为pippo.

然后,要使此处文档中的内容完全按照书面形式进行传输,而不是扩展、评估或更改,您需要引用<<.
其中任何一个(甚至部分引号也有效):

<<'EOF'
<<"EOF"
<<\EOF
<<E"O"F
<<E\OF

如果没有引用,变量的值"$LOGFILE"将扩展为其值(在您的环境中似乎为空),并丢失。

简而言之,使用这样的东西:

cat > pippo << \_EOF_
LOGFILE=test.log    
echo '#############################' >> $LOGFILE
_EOF_

相关内容