如何避免 heredoc 扩展变量?

How to avoid heredoc expanding variables?

我正在尝试使用来自 ENV 的替换字符串创建一个脚本文件,但我还想防止某些内容转义

export PLACEHOLDER1="myPlaceholder1Value"
sudo /bin/su -c "cat << EOF > /etc/init.d/my-script
#!/bin/bash

myvariable_1=toto$PLACEHOLDER1
myvariable_final=\"dynamicvar=${myvariable_1},${myvariable_2}\"
EOF
"

它的结果并不好,因为 myvariable_final 没有转义并被替换为初始化脚本依赖项($remote_fs, $syslog, $network, $time)

#!/bin/bash

myvariable_1=totomyPlaceholder1Value
myvariable_2=titimyPlaceholder2Value
myvariable_final="dynamicvar=,"

如果我尝试在美元 $ 后面加上反斜杠 \,我设法避免了替换,但我得到了不需要的反斜杠 \:

export PLACEHOLDER1="myPlaceholder1Value"
export PLACEHOLDER2="myPlaceholder2Value"
sudo /bin/su -c "cat << EOF > /etc/init.d/my-script
#!/bin/bash

myvariable_1=toto$PLACEHOLDER1
myvariable_2=titi$PLACEHOLDER2
myvariable_final=\"dynamicvar=$\{myvariable_1},$\{myvariable_2}\"
EOF
"

结果:

#!/bin/bash

myvariable_1=totomyPlaceholder1Value
myvariable_2=titimyPlaceholder2Value
myvariable_final="dynamicvar=$\{myvariable_1},$\{myvariable_2}"

Wanted/attended 结果应该是:

#!/bin/bash

myvariable_1=totomyPlaceholder1Value
myvariable_2=titimyPlaceholder2Value
myvariable_final="dynamicvar=${myvariable_1},${myvariable_2}"

通过在 EOF 周围加上引号解决,并在需要时使用反斜杠控制转义

export PLACEHOLDER1="myPlaceholder1Value"
export PLACEHOLDER2="myPlaceholder2Value"
sudo /bin/su -c "cat << 'EOF' > /etc/init.d/my-script
#!/bin/bash

myvariable_1=toto$PLACEHOLDER1
myvariable_2=titi$PLACEHOLDER2
myvariable_final=\"dynamicvar=${myvariable_1},${myvariable_2}\"
EOF
"

当使用 su 命令时,将命令本身放在单引号中,并用反斜杠将 $ 转义。占位符变量必须在命令 bash 上下文中设置(此处在 su 之后)。所以你需要做某事

su -c 'ph="ph"; cat << EOF > script 
varinscript=$ph
var=${var}
EOF'

只需使用'EOF'来防止变量扩展:

sudo /bin/su -c "cat << 'EOF' > /etc/init.d/my-script
#                       ^   ^

来自 man bash:

Here Documents

This type of redirection instructs the shell to read input from the current source until a line containing only delimiter (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command.

The format of here-documents is:

      <<[-]word
              here-document
      delimiter

No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \<newline> is ignored, and \ must be used to quote the characters \, $, and `.