考虑以下代码:
for domain; do
cat << EOF > "/etc/nginx/sites-available/${domain}.conf"
My \domain is ${domain}.
EOF
done
请注意,路径/etc/nginx/sites-available/${domain}.conf
用引号引起来。这是最佳实践还是由于变量替换而完成的?如果是变量替换,那么将定界符名称 ( EOF
) 包装起来不是更好或更常见吗?
答案1
引用包含变量的表达式是最佳实践(而不是仅仅成为一个习俗) 部分因为变量扩展:
例如,如果变量扩展为包含空格的字符串,那么您的代码最终将写入错误的文件。引用heredoc关键字确实会影响变量扩展,但与引用影响字符串的方式不同:
具体来说,引用heredoc关键字可以防止变量扩展。
无论如何,有问题的路径不是heredoc主体的一部分(从行开始)后第一个分隔符)因此不会受到影响 - 它必须被独立引用。
另请注意(尽管这与您的问题无关)代码片段中的heredoc无效,因为结束分隔符是缩进的。考虑以下摘录高级 Bash 脚本指南:
闭幕式限制字符串,在此处文档的最后一行,必须从第一的字符位置。可以有没有前导空格。限制字符串后面的尾随空格同样会导致意外行为。空格会阻止限制字符串被识别。
这里的例外是<<-
样式heredocs,它忽略制表符缩进,并且还允许结束分隔符进行制表符缩进。以下段落摘自以下段落对此进行了描述伍利奇狂欢 维基:
如果您使用
<<-END
而不是<<END
作为 Heredoc 运算符,Bash 会删除 Heredoc 内容每行开头的所有制表符,然后再将其发送到命令。这样,您仍然可以使用制表符(但不能使用空格)来缩进 Heredoc 内容和代码的其余部分。这些选项卡不会发送到接收您的 Heredoc 的命令。您还可以使用制表符来缩进哨兵字符串。