在 cat 中重定向 Makefile 文档消失变量和换行符

在 cat 中重定向 Makefile 文档消失变量和换行符

执行:

cat <<MAKE >> /etc/apache2/sites-available/Makefile1
% :
    printf '%s\n' \
    '<VirtualHost *:80>' \
    'DocumentRoot "/var/www/html/$@">' \
    'ServerName $@' \
    '<Directory "/var/www/html/$@">' \
    'Options +SymLinksIfOwnerMatch' \
    'Require all granted' \
    '</Directory>' \
    'ServerAlias www.$@' \
    '</VirtualHost>' \
    > "$@"
    a2ensite "$@"
    systemctl restart apache2.service
    mv /etc/apache2/sites-available/$@ /etc/apache2/sites-available/[email protected]
    # Before quotes == Tabuilations. Inside quotes == Spaces. After quotes == Spaces (1 space before backslash for line break). Also avoid any other spaces.
MAKE

运行后创建此cd /etc/apache2/sites-available/ && make contentperhour.com

% :
printf '%s\n' '<VirtualHost *:80>' 'DocumentRoot "/var/www/html/">' 'ServerName ' '<Directory "/var/www/html/">' 'Options +SymLinksIfOwnerMatch' 'Require all granted' '</Directory>' 'ServerAlias www.' '</VirtualHost>' > ""
a2ensite ""
systemctl restart apache2.service
mv /etc/apache2/sites-available/ /etc/apache2/sites-available/.conf

如您所见,执行后,第二个示例中的相关行只是一长行(没有换行符,用反斜杠表示,并且变量$@没有出现在任何地方。为什么重定向后会出现这种情况?

答案1

从以下Here Documents部分man bash

这里文档的格式是:

     <<[-]word
            here-document
     delimiter

不对 word 执行任何参数和变量扩展、命令替换、算术扩展或路径名扩展。如果word中的任何字符被引用,则分隔符是word删除引号的结果,并且此处文档中的行不会被扩展。 如果 word 不加引号,则此处文档的所有行都会进行参数扩展、命令替换和算术扩展,字符序列 \ 被忽略,并且必须使用 \ 来引用字符 \、$ 和 `。

由于MAKE在您的示例中未加引号,因此\被忽略并$@正在扩展(可能是空参数列表)。

解决方案是引用标记(的任何部分),例如

cat <<\MAKE >> /etc/apache2/sites-available/Makefile1

或者

cat <<"MAKE" >> /etc/apache2/sites-available/Makefile1

或提供所需的转义,例如\\用于行延续\$@$@

相关内容