【问题标题】:How to avoid heredoc expanding variables? [duplicate]如何避免 heredoc 扩展变量? [复制]
【发布时间】:2023-01-13 03:33:53
【问题描述】:

我正在尝试使用来自 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}"

通缉/出席的结果应该是:

#!/bin/bash

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

通过在周围加上引号来解决结束符如下所示,并在需要时使用反斜杠控制转义

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
"

【问题讨论】:

  • 请注意,只有第一个“EOF”需要引号!
  • 如果你使用带引号的'EOF',它不会替换,但例如在我的例子中我需要一些变量被替换,一些环境变量不被转义。我们该怎么做。

标签: bash escaping substitution heredoc


【解决方案1】:

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

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

来自man bash

这里文件

这种类型的重定向指示 shell 从 当前源,直到一行只包含定界符(没有 尾随空白)被看到。到那时为止阅读的所有行都是 然后用作命令的标准输入。

这里文档的格式是:

      <<[-]word
              here-document
      delimiter

无参数扩展、命令替换、算术扩展、 或对 word 执行路径名扩展。如果单词中有任何字符 被引用,分隔符是在 word 上去除引号的结果,并且 此处文档中的行未展开。如果单词是 未引用,此处文档的所有行都受参数约束 扩展、命令替换和算术扩展.在里面 后一种情况,字符序列&lt;newline&gt;被忽略, 必须用于引用字符$`

【讨论】:

  • 'EOF' 周围的引号起到了转义的作用,我能够控制替换的内容并且不替换 wnat
  • 奇怪的是,当我执行此操作时(创建帮助程序脚本)在 shell 脚本中,它无法识别关闭的 'EOF'。它只包括父脚本的其余部分。
  • 最后我弄清楚我做错了什么。 'EOF' 应该只用于开始标签。不适用于结束标记。只需使用不带引号的EOF
  • @SridharSarnobat 哦,有趣。随意编辑答案以包含此内容
【解决方案2】:

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

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

【讨论】:

  • 您的回答很好,但我想防止再次将所有 env/export VAR 放回命令中。
  • 所以在那种情况下不需要引用 EOF 吗?
猜你喜欢
  • 2015-03-11
  • 2020-06-24
  • 2017-08-23
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 2019-08-30
相关资源
最近更新 更多